209 }
210
211 private static native String getLocalHostname();
212 private static native int getJvmPID();
213
214 void postInit(XCreateWindowParams params) {
215 super.postInit(params);
216
217 // Init WM_PROTOCOLS atom
218 initWMProtocols();
219
220 // Set _NET_WM_PID and WM_CLIENT_MACHINE using this JVM
221 XAtom.get("WM_CLIENT_MACHINE").setProperty(getWindow(), getLocalHostname());
222 XAtom.get("_NET_WM_PID").setCard32Property(getWindow(), getJvmPID());
223
224 // Set WM_TRANSIENT_FOR and group_leader
225 Window t_window = (Window)target;
226 Window owner = t_window.getOwner();
227 if (owner != null) {
228 ownerPeer = (XWindowPeer)owner.getPeer();
229 if (focusLog.isLoggable(PlatformLogger.FINER)) {
230 focusLog.finer("Owner is " + owner);
231 focusLog.finer("Owner peer is " + ownerPeer);
232 focusLog.finer("Owner X window " + Long.toHexString(ownerPeer.getWindow()));
233 focusLog.finer("Owner content X window " + Long.toHexString(ownerPeer.getContentWindow()));
234 }
235 // as owner window may be an embedded window, we must get a toplevel window
236 // to set as TRANSIENT_FOR hint
237 long ownerWindow = ownerPeer.getWindow();
238 if (ownerWindow != 0) {
239 XToolkit.awtLock();
240 try {
241 // Set WM_TRANSIENT_FOR
242 if (focusLog.isLoggable(PlatformLogger.FINE)) {
243 focusLog.fine("Setting transient on " + Long.toHexString(getWindow())
244 + " for " + Long.toHexString(ownerWindow));
245 }
246 setToplevelTransientFor(this, ownerPeer, false, true);
247
248 // Set group leader
249 XWMHints hints = getWMHints();
250 hints.set_flags(hints.get_flags() | (int)XUtilConstants.WindowGroupHint);
251 hints.set_window_group(ownerWindow);
252 XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
253 }
254 finally {
255 XToolkit.awtUnlock();
256 }
257 }
258 }
259
260 if (owner != null || isSimpleWindow()) {
261 XNETProtocol protocol = XWM.getWM().getNETProtocol();
262 if (protocol != null && protocol.active()) {
284 setSaveUnder(true);
285
286 updateIconImages();
287
288 updateShape();
289 updateOpacity();
290 // no need in updateOpaque() as it is no-op
291 }
292
293 public void updateIconImages() {
294 Window target = (Window)this.target;
295 java.util.List<Image> iconImages = ((Window)target).getIconImages();
296 XWindowPeer ownerPeer = getOwnerPeer();
297 winAttr.icons = new ArrayList<XIconInfo>();
298 if (iconImages.size() != 0) {
299 //read icon images from target
300 winAttr.iconsInherited = false;
301 for (Iterator<Image> i = iconImages.iterator(); i.hasNext(); ) {
302 Image image = i.next();
303 if (image == null) {
304 if (log.isLoggable(PlatformLogger.FINEST)) {
305 log.finest("XWindowPeer.updateIconImages: Skipping the image passed into Java because it's null.");
306 }
307 continue;
308 }
309 XIconInfo iconInfo;
310 try {
311 iconInfo = new XIconInfo(image);
312 } catch (Exception e){
313 if (log.isLoggable(PlatformLogger.FINEST)) {
314 log.finest("XWindowPeer.updateIconImages: Perhaps the image passed into Java is broken. Skipping this icon.");
315 }
316 continue;
317 }
318 if (iconInfo.isValid()) {
319 winAttr.icons.add(iconInfo);
320 }
321 }
322 }
323
324 // Fix for CR#6425089
325 winAttr.icons = normalizeIconImages(winAttr.icons);
326
327 if (winAttr.icons.size() == 0) {
328 //target.icons is empty or all icon images are broken
329 if (ownerPeer != null) {
330 //icon is inherited from parent
331 winAttr.iconsInherited = true;
332 winAttr.icons = ownerPeer.getIconInfo();
333 } else {
364 int scaledHeight = height;
365 while (scaledWidth > PREFERRED_SIZE_FOR_ICON ||
366 scaledHeight > PREFERRED_SIZE_FOR_ICON) {
367 scaledWidth = scaledWidth / 2;
368 scaledHeight = scaledHeight / 2;
369 }
370
371 icon.setScaledSize(scaledWidth, scaledHeight);
372 length = icon.getRawLength();
373 }
374
375 if (totalLength + length <= MAXIMUM_BUFFER_LENGTH_NET_WM_ICON) {
376 totalLength += length;
377 result.add(icon);
378 if (width > PREFERRED_SIZE_FOR_ICON || height > PREFERRED_SIZE_FOR_ICON) {
379 haveLargeIcon = true;
380 }
381 }
382 }
383
384 if (iconLog.isLoggable(PlatformLogger.FINEST)) {
385 iconLog.finest(">>> Length_ of buffer of icons data: " + totalLength +
386 ", maximum length: " + MAXIMUM_BUFFER_LENGTH_NET_WM_ICON);
387 }
388
389 return result;
390 }
391
392 /*
393 * Dumps each icon from the list
394 */
395 static void dumpIcons(java.util.List<XIconInfo> icons) {
396 if (iconLog.isLoggable(PlatformLogger.FINEST)) {
397 iconLog.finest(">>> Sizes of icon images:");
398 for (Iterator<XIconInfo> i = icons.iterator(); i.hasNext(); ) {
399 iconLog.finest(" {0}", i.next());
400 }
401 }
402 }
403
404 public void recursivelySetIcon(java.util.List<XIconInfo> icons) {
405 dumpIcons(winAttr.icons);
406 setIconHints(icons);
407 Window target = (Window)this.target;
408 Window[] children = target.getOwnedWindows();
409 int cnt = children.length;
410 for (int i = 0; i < cnt; i++) {
411 ComponentPeer childPeer = children[i].getPeer();
412 if (childPeer != null && childPeer instanceof XWindowPeer) {
413 if (((XWindowPeer)childPeer).winAttr.iconsInherited) {
414 ((XWindowPeer)childPeer).winAttr.icons = icons;
415 ((XWindowPeer)childPeer).recursivelySetIcon(icons);
416 }
650 postEvent(wrapInSequenced((AWTEvent) we));
651 }
652 public void handleWindowFocusOutSync(Window oppositeWindow, long serial) {
653 WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
654 XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
655 XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
656 sendEvent(we);
657 }
658
659 /* --- DisplayChangedListener Stuff --- */
660
661 /* Xinerama
662 * called to check if we've been moved onto a different screen
663 * Based on checkNewXineramaScreen() in awt_GraphicsEnv.c
664 */
665 public void checkIfOnNewScreen(Rectangle newBounds) {
666 if (!XToolkit.localEnv.runningXinerama()) {
667 return;
668 }
669
670 if (log.isLoggable(PlatformLogger.FINEST)) {
671 log.finest("XWindowPeer: Check if we've been moved to a new screen since we're running in Xinerama mode");
672 }
673
674 int area = newBounds.width * newBounds.height;
675 int intAmt, vertAmt, horizAmt;
676 int largestAmt = 0;
677 int curScreenNum = ((X11GraphicsDevice)getGraphicsConfiguration().getDevice()).getScreen();
678 int newScreenNum = 0;
679 GraphicsDevice gds[] = XToolkit.localEnv.getScreenDevices();
680 GraphicsConfiguration newGC = null;
681 Rectangle screenBounds;
682
683 for (int i = 0; i < gds.length; i++) {
684 screenBounds = gds[i].getDefaultConfiguration().getBounds();
685 if (newBounds.intersects(screenBounds)) {
686 horizAmt = Math.min(newBounds.x + newBounds.width,
687 screenBounds.x + screenBounds.width) -
688 Math.max(newBounds.x, screenBounds.x);
689 vertAmt = Math.min(newBounds.y + newBounds.height,
690 screenBounds.y + screenBounds.height)-
691 Math.max(newBounds.y, screenBounds.y);
692 intAmt = horizAmt * vertAmt;
693 if (intAmt == area) {
694 // Completely on this screen - done!
695 newScreenNum = i;
696 newGC = gds[i].getDefaultConfiguration();
697 break;
698 }
699 if (intAmt > largestAmt) {
700 largestAmt = intAmt;
701 newScreenNum = i;
702 newGC = gds[i].getDefaultConfiguration();
703 }
704 }
705 }
706 if (newScreenNum != curScreenNum) {
707 if (log.isLoggable(PlatformLogger.FINEST)) {
708 log.finest("XWindowPeer: Moved to a new screen");
709 }
710 executeDisplayChangedOnEDT(newGC);
711 }
712 }
713
714 /**
715 * Helper method that executes the displayChanged(screen) method on
716 * the event dispatch thread. This method is used in the Xinerama case
717 * and after display mode change events.
718 */
719 private void executeDisplayChangedOnEDT(final GraphicsConfiguration gc) {
720 Runnable dc = new Runnable() {
721 public void run() {
722 AWTAccessor.getComponentAccessor().
723 setGraphicsConfiguration((Component)target, gc);
724 }
725 };
726 SunToolkit.executeOnEventHandlerThread((Component)target, dc);
727 }
762 repositionSecurityWarning();
763 }
764
765 final void requestXFocus(long time) {
766 requestXFocus(time, true);
767 }
768
769 final void requestXFocus() {
770 requestXFocus(0, false);
771 }
772
773 /**
774 * Requests focus to this top-level. Descendants should override to provide
775 * implementations based on a class of top-level.
776 */
777 protected void requestXFocus(long time, boolean timeProvided) {
778 // Since in XAWT focus is synthetic and all basic Windows are
779 // override_redirect all we can do is check whether our parent
780 // is active. If it is - we can freely synthesize focus transfer.
781 // Luckily, this logic is already implemented in requestWindowFocus.
782 if (focusLog.isLoggable(PlatformLogger.FINE)) {
783 focusLog.fine("Requesting window focus");
784 }
785 requestWindowFocus(time, timeProvided);
786 }
787
788 public final boolean focusAllowedFor() {
789 if (isNativelyNonFocusableWindow()) {
790 return false;
791 }
792 /*
793 Window target = (Window)this.target;
794 if (!target.isVisible() ||
795 !target.isEnabled() ||
796 !target.isFocusable())
797 {
798 return false;
799 }
800 */
801 if (isModalBlocked()) {
802 return false;
803 }
804 return true;
805 }
806
807 public void handleFocusEvent(XEvent xev) {
808 XFocusChangeEvent xfe = xev.get_xfocus();
809 FocusEvent fe;
810 if (focusLog.isLoggable(PlatformLogger.FINE)) {
811 focusLog.fine("{0}", xfe);
812 }
813 if (isEventDisabled(xev)) {
814 return;
815 }
816 if (xev.get_type() == XConstants.FocusIn)
817 {
818 // If this window is non-focusable don't post any java focus event
819 if (focusAllowedFor()) {
820 if (xfe.get_mode() == XConstants.NotifyNormal // Normal notify
821 || xfe.get_mode() == XConstants.NotifyWhileGrabbed) // Alt-Tab notify
822 {
823 handleWindowFocusIn(xfe.get_serial());
824 }
825 }
826 }
827 else
828 {
829 if (xfe.get_mode() == XConstants.NotifyNormal // Normal notify
830 || xfe.get_mode() == XConstants.NotifyWhileGrabbed) // Alt-Tab notify
975 try {
976 if (qt.execute() == 0) {
977 return 0;
978 }
979 root = qt.get_root();
980 wi = qt.get_parent();
981 } finally {
982 qt.dispose();
983 }
984
985 } while (wi != root);
986
987 return ret;
988 }
989
990 private static boolean isDesktopWindow( long wi ) {
991 return XWM.getWM().isDesktopWindow( wi );
992 }
993
994 private void updateAlwaysOnTop() {
995 if (log.isLoggable(PlatformLogger.FINE)) {
996 log.fine("Promoting always-on-top state {0}", Boolean.valueOf(alwaysOnTop));
997 }
998 XWM.getWM().setLayer(this,
999 alwaysOnTop ?
1000 XLayerProtocol.LAYER_ALWAYS_ON_TOP :
1001 XLayerProtocol.LAYER_NORMAL);
1002 }
1003
1004 public void updateAlwaysOnTopState() {
1005 this.alwaysOnTop = ((Window) this.target).isAlwaysOnTop();
1006 updateAlwaysOnTop();
1007 }
1008
1009 boolean isLocationByPlatform() {
1010 return locationByPlatform;
1011 }
1012
1013 private void promoteDefaultPosition() {
1014 this.locationByPlatform = ((Window)target).isLocationByPlatform();
1015 if (locationByPlatform) {
1157 show = true;
1158 }
1159 }
1160 }
1161
1162 warningWindow.setSecurityWarningVisible(show, true);
1163 }
1164
1165 boolean isOverrideRedirect() {
1166 return XWM.getWMID() == XWM.OPENLOOK_WM ||
1167 Window.Type.POPUP.equals(getWindowType());
1168 }
1169
1170 final boolean isOLWMDecorBug() {
1171 return XWM.getWMID() == XWM.OPENLOOK_WM &&
1172 winAttr.nativeDecor == false;
1173 }
1174
1175 public void dispose() {
1176 if (isGrabbed()) {
1177 if (grabLog.isLoggable(PlatformLogger.FINE)) {
1178 grabLog.fine("Generating UngrabEvent on {0} because of the window disposal", this);
1179 }
1180 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
1181 }
1182
1183 SunToolkit.awtLock();
1184
1185 try {
1186 windows.remove(this);
1187 } finally {
1188 SunToolkit.awtUnlock();
1189 }
1190
1191 if (warningWindow != null) {
1192 warningWindow.destroy();
1193 }
1194
1195 removeRootPropertyEventDispatcher();
1196 mustControlStackPosition = false;
1197 super.dispose();
1502 }
1503 } finally {
1504 qt.dispose();
1505 }
1506 }
1507 return javaToplevels;
1508 }
1509
1510 public void setModalBlocked(Dialog d, boolean blocked) {
1511 setModalBlocked(d, blocked, null);
1512 }
1513 public void setModalBlocked(Dialog d, boolean blocked,
1514 Vector<XWindowPeer> javaToplevels)
1515 {
1516 XToolkit.awtLock();
1517 try {
1518 // State lock should always be after awtLock
1519 synchronized(getStateLock()) {
1520 XDialogPeer blockerPeer = (XDialogPeer) AWTAccessor.getComponentAccessor().getPeer(d);
1521 if (blocked) {
1522 if (log.isLoggable(PlatformLogger.FINE)) {
1523 log.fine("{0} is blocked by {1}", this, blockerPeer);
1524 }
1525 modalBlocker = d;
1526
1527 if (isReparented() || XWM.isNonReparentingWM()) {
1528 addToTransientFors(blockerPeer, javaToplevels);
1529 } else {
1530 delayedModalBlocking = true;
1531 }
1532 } else {
1533 if (d != modalBlocker) {
1534 throw new IllegalStateException("Trying to unblock window blocked by another dialog");
1535 }
1536 modalBlocker = null;
1537
1538 if (isReparented() || XWM.isNonReparentingWM()) {
1539 removeFromTransientFors();
1540 } else {
1541 delayedModalBlocking = false;
1542 }
1895 typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_UTILITY;
1896 break;
1897 case POPUP:
1898 typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_POPUP_MENU;
1899 break;
1900 }
1901
1902 if (typeAtom != null) {
1903 XAtomList wtype = new XAtomList();
1904 wtype.add(typeAtom);
1905 protocol.XA_NET_WM_WINDOW_TYPE.
1906 setAtomListProperty(getWindow(), wtype);
1907 } else {
1908 protocol.XA_NET_WM_WINDOW_TYPE.
1909 DeleteProperty(getWindow());
1910 }
1911 }
1912
1913 @Override
1914 public void xSetVisible(boolean visible) {
1915 if (log.isLoggable(PlatformLogger.FINE)) {
1916 log.fine("Setting visible on " + this + " to " + visible);
1917 }
1918 XToolkit.awtLock();
1919 try {
1920 this.visible = visible;
1921 if (visible) {
1922 applyWindowType();
1923 XlibWrapper.XMapRaised(XToolkit.getDisplay(), getWindow());
1924 } else {
1925 XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());
1926 }
1927 XlibWrapper.XFlush(XToolkit.getDisplay());
1928 }
1929 finally {
1930 XToolkit.awtUnlock();
1931 }
1932 }
1933
1934 // should be synchronized on awtLock
1935 private int dropTargetCount = 0;
2037 XToolkit.awtUnlock();
2038 }
2039 }
2040
2041 public void setGrab(boolean grab) {
2042 this.grab = grab;
2043 if (grab) {
2044 pressTarget = this;
2045 grabInput();
2046 } else {
2047 ungrabInput();
2048 }
2049 }
2050
2051 public boolean isGrabbed() {
2052 return grab && XAwtState.getGrabWindow() == this;
2053 }
2054
2055 public void handleXCrossingEvent(XEvent xev) {
2056 XCrossingEvent xce = xev.get_xcrossing();
2057 if (grabLog.isLoggable(PlatformLogger.FINE)) {
2058 grabLog.fine("{0}, when grabbed {1}, contains {2}",
2059 xce, isGrabbed(), containsGlobal(xce.get_x_root(), xce.get_y_root()));
2060 }
2061 if (isGrabbed()) {
2062 // When window is grabbed, all events are dispatched to
2063 // it. Retarget them to the corresponding windows (notice
2064 // that XBaseWindow.dispatchEvent does the opposite
2065 // translation)
2066 // Note that we need to retarget XCrossingEvents to content window
2067 // since it generates MOUSE_ENTERED/MOUSE_EXITED for frame and dialog.
2068 // (fix for 6390326)
2069 XBaseWindow target = XToolkit.windowToXWindow(xce.get_window());
2070 if (grabLog.isLoggable(PlatformLogger.FINER)) {
2071 grabLog.finer(" - Grab event target {0}", target);
2072 }
2073 if (target != null && target != this) {
2074 target.dispatchEvent(xev);
2075 return;
2076 }
2077 }
2078 super.handleXCrossingEvent(xev);
2079 }
2080
2081 public void handleMotionNotify(XEvent xev) {
2082 XMotionEvent xme = xev.get_xmotion();
2083 if (grabLog.isLoggable(PlatformLogger.FINER)) {
2084 grabLog.finer("{0}, when grabbed {1}, contains {2}",
2085 xme, isGrabbed(), containsGlobal(xme.get_x_root(), xme.get_y_root()));
2086 }
2087 if (isGrabbed()) {
2088 boolean dragging = false;
2089 final int buttonsNumber = XToolkit.getNumberOfButtonsForMask();
2090
2091 for (int i = 0; i < buttonsNumber; i++){
2092 // here is the bug in WM: extra buttons doesn't have state!=0 as they should.
2093 if ((i != 4) && (i != 5)){
2094 dragging = dragging || ((xme.get_state() & XlibUtil.getButtonMask(i + 1)) != 0);
2095 }
2096 }
2097 // When window is grabbed, all events are dispatched to
2098 // it. Retarget them to the corresponding windows (notice
2099 // that XBaseWindow.dispatchEvent does the opposite
2100 // translation)
2101 XBaseWindow target = XToolkit.windowToXWindow(xme.get_window());
2102 if (dragging && pressTarget != target) {
2103 // for some reasons if we grab input MotionNotify for drag is reported with target
2104 // to underlying window, not to window on which we have initiated drag
2105 // so we need to retarget them. Here I use simplified logic which retarget all
2106 // such events to source of mouse press (or the grabber). It helps with fix for 6390326.
2107 // So, I do not want to implement complicated logic for better retargeting.
2108 target = pressTarget.isVisible() ? pressTarget : this;
2109 xme.set_window(target.getWindow());
2110 Point localCoord = target.toLocal(xme.get_x_root(), xme.get_y_root());
2111 xme.set_x(localCoord.x);
2112 xme.set_y(localCoord.y);
2113 }
2114 if (grabLog.isLoggable(PlatformLogger.FINER)) {
2115 grabLog.finer(" - Grab event target {0}", target);
2116 }
2117 if (target != null) {
2118 if (target != getContentXWindow() && target != this) {
2119 target.dispatchEvent(xev);
2120 return;
2121 }
2122 }
2123
2124 // note that we need to pass dragging events to the grabber (6390326)
2125 // see comment above for more inforamtion.
2126 if (!containsGlobal(xme.get_x_root(), xme.get_y_root()) && !dragging) {
2127 // Outside of Java
2128 return;
2129 }
2130 }
2131 super.handleMotionNotify(xev);
2132 }
2133
2134 // we use it to retarget mouse drag and mouse release during grab.
2135 private XBaseWindow pressTarget = this;
2136
2137 public void handleButtonPressRelease(XEvent xev) {
2138 XButtonEvent xbe = xev.get_xbutton();
2139
2140 /*
2141 * Ignore the buttons above 20 due to the bit limit for
2142 * InputEvent.BUTTON_DOWN_MASK.
2143 * One more bit is reserved for FIRST_HIGH_BIT.
2144 */
2145 if (xbe.get_button() > SunToolkit.MAX_BUTTONS_SUPPORTED) {
2146 return;
2147 }
2148 if (grabLog.isLoggable(PlatformLogger.FINE)) {
2149 grabLog.fine("{0}, when grabbed {1}, contains {2} ({3}, {4}, {5}x{6})",
2150 xbe, isGrabbed(), containsGlobal(xbe.get_x_root(), xbe.get_y_root()), getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight());
2151 }
2152 if (isGrabbed()) {
2153 // When window is grabbed, all events are dispatched to
2154 // it. Retarget them to the corresponding windows (notice
2155 // that XBaseWindow.dispatchEvent does the opposite
2156 // translation)
2157 XBaseWindow target = XToolkit.windowToXWindow(xbe.get_window());
2158 try {
2159 if (grabLog.isLoggable(PlatformLogger.FINER)) {
2160 grabLog.finer(" - Grab event target {0} (press target {1})", target, pressTarget);
2161 }
2162 if (xbe.get_type() == XConstants.ButtonPress
2163 && xbe.get_button() == XConstants.buttons[0])
2164 {
2165 // need to keep it to retarget mouse release
2166 pressTarget = target;
2167 } else if (xbe.get_type() == XConstants.ButtonRelease
2168 && xbe.get_button() == XConstants.buttons[0]
2169 && pressTarget != target)
2170 {
2171 // during grab we do receive mouse release on different component (not on the source
2172 // of mouse press). So we need to retarget it.
2173 // see 6390326 for more information.
2174 target = pressTarget.isVisible() ? pressTarget : this;
2175 xbe.set_window(target.getWindow());
2176 Point localCoord = target.toLocal(xbe.get_x_root(), xbe.get_y_root());
2177 xbe.set_x(localCoord.x);
2178 xbe.set_y(localCoord.y);
2179 pressTarget = this;
2180 }
2181 if (target != null && target != getContentXWindow() && target != this) {
2182 target.dispatchEvent(xev);
2183 return;
2184 }
2185 } finally {
2186 if (target != null) {
2187 // Target is either us or our content window -
2188 // check that event is inside. 'Us' in case of
2189 // shell will mean that this will also filter out press on title
2190 if ((target == this || target == getContentXWindow()) && !containsGlobal(xbe.get_x_root(), xbe.get_y_root())) {
2191 // Outside this toplevel hierarchy
2192 // According to the specification of UngrabEvent, post it
2193 // when press occurs outside of the window and not on its owned windows
2194 if (xbe.get_type() == XConstants.ButtonPress) {
2195 if (grabLog.isLoggable(PlatformLogger.FINE)) {
2196 grabLog.fine("Generating UngrabEvent on {0} because not inside of shell", this);
2197 }
2198 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2199 return;
2200 }
2201 }
2202 // First, get the toplevel
2203 XWindowPeer toplevel = target.getToplevelXWindow();
2204 if (toplevel != null) {
2205 Window w = (Window)toplevel.target;
2206 while (w != null && toplevel != this && !(toplevel instanceof XDialogPeer)) {
2207 w = (Window) AWTAccessor.getComponentAccessor().getParent(w);
2208 if (w != null) {
2209 toplevel = (XWindowPeer) AWTAccessor.getComponentAccessor().getPeer(w);
2210 }
2211 }
2212 if (w == null || (w != this.target && w instanceof Dialog)) {
2213 // toplevel == null - outside of
2214 // hierarchy, toplevel is Dialog - should
2215 // send ungrab (but shouldn't for Window)
2216 if (grabLog.isLoggable(PlatformLogger.FINE)) {
2217 grabLog.fine("Generating UngrabEvent on {0} because hierarchy ended", this);
2218 }
2219 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2220 }
2221 } else {
2222 // toplevel is null - outside of hierarchy
2223 if (grabLog.isLoggable(PlatformLogger.FINE)) {
2224 grabLog.fine("Generating UngrabEvent on {0} because toplevel is null", this);
2225 }
2226 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2227 return;
2228 }
2229 } else {
2230 // target doesn't map to XAWT window - outside of hierarchy
2231 if (grabLog.isLoggable(PlatformLogger.FINE)) {
2232 grabLog.fine("Generating UngrabEvent on because target is null {0}", this);
2233 }
2234 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2235 return;
2236 }
2237 }
2238 }
2239 super.handleButtonPressRelease(xev);
2240 }
2241
2242 public void print(Graphics g) {
2243 // We assume we print the whole frame,
2244 // so we expect no clip was set previously
2245 Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
2246 if (shape != null) {
2247 g.setClip(shape);
2248 }
2249 super.print(g);
2250 }
2251
|
209 }
210
211 private static native String getLocalHostname();
212 private static native int getJvmPID();
213
214 void postInit(XCreateWindowParams params) {
215 super.postInit(params);
216
217 // Init WM_PROTOCOLS atom
218 initWMProtocols();
219
220 // Set _NET_WM_PID and WM_CLIENT_MACHINE using this JVM
221 XAtom.get("WM_CLIENT_MACHINE").setProperty(getWindow(), getLocalHostname());
222 XAtom.get("_NET_WM_PID").setCard32Property(getWindow(), getJvmPID());
223
224 // Set WM_TRANSIENT_FOR and group_leader
225 Window t_window = (Window)target;
226 Window owner = t_window.getOwner();
227 if (owner != null) {
228 ownerPeer = (XWindowPeer)owner.getPeer();
229 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
230 focusLog.finer("Owner is " + owner);
231 focusLog.finer("Owner peer is " + ownerPeer);
232 focusLog.finer("Owner X window " + Long.toHexString(ownerPeer.getWindow()));
233 focusLog.finer("Owner content X window " + Long.toHexString(ownerPeer.getContentWindow()));
234 }
235 // as owner window may be an embedded window, we must get a toplevel window
236 // to set as TRANSIENT_FOR hint
237 long ownerWindow = ownerPeer.getWindow();
238 if (ownerWindow != 0) {
239 XToolkit.awtLock();
240 try {
241 // Set WM_TRANSIENT_FOR
242 if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
243 focusLog.fine("Setting transient on " + Long.toHexString(getWindow())
244 + " for " + Long.toHexString(ownerWindow));
245 }
246 setToplevelTransientFor(this, ownerPeer, false, true);
247
248 // Set group leader
249 XWMHints hints = getWMHints();
250 hints.set_flags(hints.get_flags() | (int)XUtilConstants.WindowGroupHint);
251 hints.set_window_group(ownerWindow);
252 XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
253 }
254 finally {
255 XToolkit.awtUnlock();
256 }
257 }
258 }
259
260 if (owner != null || isSimpleWindow()) {
261 XNETProtocol protocol = XWM.getWM().getNETProtocol();
262 if (protocol != null && protocol.active()) {
284 setSaveUnder(true);
285
286 updateIconImages();
287
288 updateShape();
289 updateOpacity();
290 // no need in updateOpaque() as it is no-op
291 }
292
293 public void updateIconImages() {
294 Window target = (Window)this.target;
295 java.util.List<Image> iconImages = ((Window)target).getIconImages();
296 XWindowPeer ownerPeer = getOwnerPeer();
297 winAttr.icons = new ArrayList<XIconInfo>();
298 if (iconImages.size() != 0) {
299 //read icon images from target
300 winAttr.iconsInherited = false;
301 for (Iterator<Image> i = iconImages.iterator(); i.hasNext(); ) {
302 Image image = i.next();
303 if (image == null) {
304 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
305 log.finest("XWindowPeer.updateIconImages: Skipping the image passed into Java because it's null.");
306 }
307 continue;
308 }
309 XIconInfo iconInfo;
310 try {
311 iconInfo = new XIconInfo(image);
312 } catch (Exception e){
313 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
314 log.finest("XWindowPeer.updateIconImages: Perhaps the image passed into Java is broken. Skipping this icon.");
315 }
316 continue;
317 }
318 if (iconInfo.isValid()) {
319 winAttr.icons.add(iconInfo);
320 }
321 }
322 }
323
324 // Fix for CR#6425089
325 winAttr.icons = normalizeIconImages(winAttr.icons);
326
327 if (winAttr.icons.size() == 0) {
328 //target.icons is empty or all icon images are broken
329 if (ownerPeer != null) {
330 //icon is inherited from parent
331 winAttr.iconsInherited = true;
332 winAttr.icons = ownerPeer.getIconInfo();
333 } else {
364 int scaledHeight = height;
365 while (scaledWidth > PREFERRED_SIZE_FOR_ICON ||
366 scaledHeight > PREFERRED_SIZE_FOR_ICON) {
367 scaledWidth = scaledWidth / 2;
368 scaledHeight = scaledHeight / 2;
369 }
370
371 icon.setScaledSize(scaledWidth, scaledHeight);
372 length = icon.getRawLength();
373 }
374
375 if (totalLength + length <= MAXIMUM_BUFFER_LENGTH_NET_WM_ICON) {
376 totalLength += length;
377 result.add(icon);
378 if (width > PREFERRED_SIZE_FOR_ICON || height > PREFERRED_SIZE_FOR_ICON) {
379 haveLargeIcon = true;
380 }
381 }
382 }
383
384 if (iconLog.isLoggable(PlatformLogger.Level.FINEST)) {
385 iconLog.finest(">>> Length_ of buffer of icons data: " + totalLength +
386 ", maximum length: " + MAXIMUM_BUFFER_LENGTH_NET_WM_ICON);
387 }
388
389 return result;
390 }
391
392 /*
393 * Dumps each icon from the list
394 */
395 static void dumpIcons(java.util.List<XIconInfo> icons) {
396 if (iconLog.isLoggable(PlatformLogger.Level.FINEST)) {
397 iconLog.finest(">>> Sizes of icon images:");
398 for (Iterator<XIconInfo> i = icons.iterator(); i.hasNext(); ) {
399 iconLog.finest(" {0}", i.next());
400 }
401 }
402 }
403
404 public void recursivelySetIcon(java.util.List<XIconInfo> icons) {
405 dumpIcons(winAttr.icons);
406 setIconHints(icons);
407 Window target = (Window)this.target;
408 Window[] children = target.getOwnedWindows();
409 int cnt = children.length;
410 for (int i = 0; i < cnt; i++) {
411 ComponentPeer childPeer = children[i].getPeer();
412 if (childPeer != null && childPeer instanceof XWindowPeer) {
413 if (((XWindowPeer)childPeer).winAttr.iconsInherited) {
414 ((XWindowPeer)childPeer).winAttr.icons = icons;
415 ((XWindowPeer)childPeer).recursivelySetIcon(icons);
416 }
650 postEvent(wrapInSequenced((AWTEvent) we));
651 }
652 public void handleWindowFocusOutSync(Window oppositeWindow, long serial) {
653 WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
654 XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
655 XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
656 sendEvent(we);
657 }
658
659 /* --- DisplayChangedListener Stuff --- */
660
661 /* Xinerama
662 * called to check if we've been moved onto a different screen
663 * Based on checkNewXineramaScreen() in awt_GraphicsEnv.c
664 */
665 public void checkIfOnNewScreen(Rectangle newBounds) {
666 if (!XToolkit.localEnv.runningXinerama()) {
667 return;
668 }
669
670 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
671 log.finest("XWindowPeer: Check if we've been moved to a new screen since we're running in Xinerama mode");
672 }
673
674 int area = newBounds.width * newBounds.height;
675 int intAmt, vertAmt, horizAmt;
676 int largestAmt = 0;
677 int curScreenNum = ((X11GraphicsDevice)getGraphicsConfiguration().getDevice()).getScreen();
678 int newScreenNum = 0;
679 GraphicsDevice gds[] = XToolkit.localEnv.getScreenDevices();
680 GraphicsConfiguration newGC = null;
681 Rectangle screenBounds;
682
683 for (int i = 0; i < gds.length; i++) {
684 screenBounds = gds[i].getDefaultConfiguration().getBounds();
685 if (newBounds.intersects(screenBounds)) {
686 horizAmt = Math.min(newBounds.x + newBounds.width,
687 screenBounds.x + screenBounds.width) -
688 Math.max(newBounds.x, screenBounds.x);
689 vertAmt = Math.min(newBounds.y + newBounds.height,
690 screenBounds.y + screenBounds.height)-
691 Math.max(newBounds.y, screenBounds.y);
692 intAmt = horizAmt * vertAmt;
693 if (intAmt == area) {
694 // Completely on this screen - done!
695 newScreenNum = i;
696 newGC = gds[i].getDefaultConfiguration();
697 break;
698 }
699 if (intAmt > largestAmt) {
700 largestAmt = intAmt;
701 newScreenNum = i;
702 newGC = gds[i].getDefaultConfiguration();
703 }
704 }
705 }
706 if (newScreenNum != curScreenNum) {
707 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
708 log.finest("XWindowPeer: Moved to a new screen");
709 }
710 executeDisplayChangedOnEDT(newGC);
711 }
712 }
713
714 /**
715 * Helper method that executes the displayChanged(screen) method on
716 * the event dispatch thread. This method is used in the Xinerama case
717 * and after display mode change events.
718 */
719 private void executeDisplayChangedOnEDT(final GraphicsConfiguration gc) {
720 Runnable dc = new Runnable() {
721 public void run() {
722 AWTAccessor.getComponentAccessor().
723 setGraphicsConfiguration((Component)target, gc);
724 }
725 };
726 SunToolkit.executeOnEventHandlerThread((Component)target, dc);
727 }
762 repositionSecurityWarning();
763 }
764
765 final void requestXFocus(long time) {
766 requestXFocus(time, true);
767 }
768
769 final void requestXFocus() {
770 requestXFocus(0, false);
771 }
772
773 /**
774 * Requests focus to this top-level. Descendants should override to provide
775 * implementations based on a class of top-level.
776 */
777 protected void requestXFocus(long time, boolean timeProvided) {
778 // Since in XAWT focus is synthetic and all basic Windows are
779 // override_redirect all we can do is check whether our parent
780 // is active. If it is - we can freely synthesize focus transfer.
781 // Luckily, this logic is already implemented in requestWindowFocus.
782 if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
783 focusLog.fine("Requesting window focus");
784 }
785 requestWindowFocus(time, timeProvided);
786 }
787
788 public final boolean focusAllowedFor() {
789 if (isNativelyNonFocusableWindow()) {
790 return false;
791 }
792 /*
793 Window target = (Window)this.target;
794 if (!target.isVisible() ||
795 !target.isEnabled() ||
796 !target.isFocusable())
797 {
798 return false;
799 }
800 */
801 if (isModalBlocked()) {
802 return false;
803 }
804 return true;
805 }
806
807 public void handleFocusEvent(XEvent xev) {
808 XFocusChangeEvent xfe = xev.get_xfocus();
809 FocusEvent fe;
810 if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
811 focusLog.fine("{0}", xfe);
812 }
813 if (isEventDisabled(xev)) {
814 return;
815 }
816 if (xev.get_type() == XConstants.FocusIn)
817 {
818 // If this window is non-focusable don't post any java focus event
819 if (focusAllowedFor()) {
820 if (xfe.get_mode() == XConstants.NotifyNormal // Normal notify
821 || xfe.get_mode() == XConstants.NotifyWhileGrabbed) // Alt-Tab notify
822 {
823 handleWindowFocusIn(xfe.get_serial());
824 }
825 }
826 }
827 else
828 {
829 if (xfe.get_mode() == XConstants.NotifyNormal // Normal notify
830 || xfe.get_mode() == XConstants.NotifyWhileGrabbed) // Alt-Tab notify
975 try {
976 if (qt.execute() == 0) {
977 return 0;
978 }
979 root = qt.get_root();
980 wi = qt.get_parent();
981 } finally {
982 qt.dispose();
983 }
984
985 } while (wi != root);
986
987 return ret;
988 }
989
990 private static boolean isDesktopWindow( long wi ) {
991 return XWM.getWM().isDesktopWindow( wi );
992 }
993
994 private void updateAlwaysOnTop() {
995 if (log.isLoggable(PlatformLogger.Level.FINE)) {
996 log.fine("Promoting always-on-top state {0}", Boolean.valueOf(alwaysOnTop));
997 }
998 XWM.getWM().setLayer(this,
999 alwaysOnTop ?
1000 XLayerProtocol.LAYER_ALWAYS_ON_TOP :
1001 XLayerProtocol.LAYER_NORMAL);
1002 }
1003
1004 public void updateAlwaysOnTopState() {
1005 this.alwaysOnTop = ((Window) this.target).isAlwaysOnTop();
1006 updateAlwaysOnTop();
1007 }
1008
1009 boolean isLocationByPlatform() {
1010 return locationByPlatform;
1011 }
1012
1013 private void promoteDefaultPosition() {
1014 this.locationByPlatform = ((Window)target).isLocationByPlatform();
1015 if (locationByPlatform) {
1157 show = true;
1158 }
1159 }
1160 }
1161
1162 warningWindow.setSecurityWarningVisible(show, true);
1163 }
1164
1165 boolean isOverrideRedirect() {
1166 return XWM.getWMID() == XWM.OPENLOOK_WM ||
1167 Window.Type.POPUP.equals(getWindowType());
1168 }
1169
1170 final boolean isOLWMDecorBug() {
1171 return XWM.getWMID() == XWM.OPENLOOK_WM &&
1172 winAttr.nativeDecor == false;
1173 }
1174
1175 public void dispose() {
1176 if (isGrabbed()) {
1177 if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
1178 grabLog.fine("Generating UngrabEvent on {0} because of the window disposal", this);
1179 }
1180 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
1181 }
1182
1183 SunToolkit.awtLock();
1184
1185 try {
1186 windows.remove(this);
1187 } finally {
1188 SunToolkit.awtUnlock();
1189 }
1190
1191 if (warningWindow != null) {
1192 warningWindow.destroy();
1193 }
1194
1195 removeRootPropertyEventDispatcher();
1196 mustControlStackPosition = false;
1197 super.dispose();
1502 }
1503 } finally {
1504 qt.dispose();
1505 }
1506 }
1507 return javaToplevels;
1508 }
1509
1510 public void setModalBlocked(Dialog d, boolean blocked) {
1511 setModalBlocked(d, blocked, null);
1512 }
1513 public void setModalBlocked(Dialog d, boolean blocked,
1514 Vector<XWindowPeer> javaToplevels)
1515 {
1516 XToolkit.awtLock();
1517 try {
1518 // State lock should always be after awtLock
1519 synchronized(getStateLock()) {
1520 XDialogPeer blockerPeer = (XDialogPeer) AWTAccessor.getComponentAccessor().getPeer(d);
1521 if (blocked) {
1522 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1523 log.fine("{0} is blocked by {1}", this, blockerPeer);
1524 }
1525 modalBlocker = d;
1526
1527 if (isReparented() || XWM.isNonReparentingWM()) {
1528 addToTransientFors(blockerPeer, javaToplevels);
1529 } else {
1530 delayedModalBlocking = true;
1531 }
1532 } else {
1533 if (d != modalBlocker) {
1534 throw new IllegalStateException("Trying to unblock window blocked by another dialog");
1535 }
1536 modalBlocker = null;
1537
1538 if (isReparented() || XWM.isNonReparentingWM()) {
1539 removeFromTransientFors();
1540 } else {
1541 delayedModalBlocking = false;
1542 }
1895 typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_UTILITY;
1896 break;
1897 case POPUP:
1898 typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_POPUP_MENU;
1899 break;
1900 }
1901
1902 if (typeAtom != null) {
1903 XAtomList wtype = new XAtomList();
1904 wtype.add(typeAtom);
1905 protocol.XA_NET_WM_WINDOW_TYPE.
1906 setAtomListProperty(getWindow(), wtype);
1907 } else {
1908 protocol.XA_NET_WM_WINDOW_TYPE.
1909 DeleteProperty(getWindow());
1910 }
1911 }
1912
1913 @Override
1914 public void xSetVisible(boolean visible) {
1915 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1916 log.fine("Setting visible on " + this + " to " + visible);
1917 }
1918 XToolkit.awtLock();
1919 try {
1920 this.visible = visible;
1921 if (visible) {
1922 applyWindowType();
1923 XlibWrapper.XMapRaised(XToolkit.getDisplay(), getWindow());
1924 } else {
1925 XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());
1926 }
1927 XlibWrapper.XFlush(XToolkit.getDisplay());
1928 }
1929 finally {
1930 XToolkit.awtUnlock();
1931 }
1932 }
1933
1934 // should be synchronized on awtLock
1935 private int dropTargetCount = 0;
2037 XToolkit.awtUnlock();
2038 }
2039 }
2040
2041 public void setGrab(boolean grab) {
2042 this.grab = grab;
2043 if (grab) {
2044 pressTarget = this;
2045 grabInput();
2046 } else {
2047 ungrabInput();
2048 }
2049 }
2050
2051 public boolean isGrabbed() {
2052 return grab && XAwtState.getGrabWindow() == this;
2053 }
2054
2055 public void handleXCrossingEvent(XEvent xev) {
2056 XCrossingEvent xce = xev.get_xcrossing();
2057 if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2058 grabLog.fine("{0}, when grabbed {1}, contains {2}",
2059 xce, isGrabbed(), containsGlobal(xce.get_x_root(), xce.get_y_root()));
2060 }
2061 if (isGrabbed()) {
2062 // When window is grabbed, all events are dispatched to
2063 // it. Retarget them to the corresponding windows (notice
2064 // that XBaseWindow.dispatchEvent does the opposite
2065 // translation)
2066 // Note that we need to retarget XCrossingEvents to content window
2067 // since it generates MOUSE_ENTERED/MOUSE_EXITED for frame and dialog.
2068 // (fix for 6390326)
2069 XBaseWindow target = XToolkit.windowToXWindow(xce.get_window());
2070 if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2071 grabLog.finer(" - Grab event target {0}", target);
2072 }
2073 if (target != null && target != this) {
2074 target.dispatchEvent(xev);
2075 return;
2076 }
2077 }
2078 super.handleXCrossingEvent(xev);
2079 }
2080
2081 public void handleMotionNotify(XEvent xev) {
2082 XMotionEvent xme = xev.get_xmotion();
2083 if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2084 grabLog.finer("{0}, when grabbed {1}, contains {2}",
2085 xme, isGrabbed(), containsGlobal(xme.get_x_root(), xme.get_y_root()));
2086 }
2087 if (isGrabbed()) {
2088 boolean dragging = false;
2089 final int buttonsNumber = XToolkit.getNumberOfButtonsForMask();
2090
2091 for (int i = 0; i < buttonsNumber; i++){
2092 // here is the bug in WM: extra buttons doesn't have state!=0 as they should.
2093 if ((i != 4) && (i != 5)){
2094 dragging = dragging || ((xme.get_state() & XlibUtil.getButtonMask(i + 1)) != 0);
2095 }
2096 }
2097 // When window is grabbed, all events are dispatched to
2098 // it. Retarget them to the corresponding windows (notice
2099 // that XBaseWindow.dispatchEvent does the opposite
2100 // translation)
2101 XBaseWindow target = XToolkit.windowToXWindow(xme.get_window());
2102 if (dragging && pressTarget != target) {
2103 // for some reasons if we grab input MotionNotify for drag is reported with target
2104 // to underlying window, not to window on which we have initiated drag
2105 // so we need to retarget them. Here I use simplified logic which retarget all
2106 // such events to source of mouse press (or the grabber). It helps with fix for 6390326.
2107 // So, I do not want to implement complicated logic for better retargeting.
2108 target = pressTarget.isVisible() ? pressTarget : this;
2109 xme.set_window(target.getWindow());
2110 Point localCoord = target.toLocal(xme.get_x_root(), xme.get_y_root());
2111 xme.set_x(localCoord.x);
2112 xme.set_y(localCoord.y);
2113 }
2114 if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2115 grabLog.finer(" - Grab event target {0}", target);
2116 }
2117 if (target != null) {
2118 if (target != getContentXWindow() && target != this) {
2119 target.dispatchEvent(xev);
2120 return;
2121 }
2122 }
2123
2124 // note that we need to pass dragging events to the grabber (6390326)
2125 // see comment above for more inforamtion.
2126 if (!containsGlobal(xme.get_x_root(), xme.get_y_root()) && !dragging) {
2127 // Outside of Java
2128 return;
2129 }
2130 }
2131 super.handleMotionNotify(xev);
2132 }
2133
2134 // we use it to retarget mouse drag and mouse release during grab.
2135 private XBaseWindow pressTarget = this;
2136
2137 public void handleButtonPressRelease(XEvent xev) {
2138 XButtonEvent xbe = xev.get_xbutton();
2139
2140 /*
2141 * Ignore the buttons above 20 due to the bit limit for
2142 * InputEvent.BUTTON_DOWN_MASK.
2143 * One more bit is reserved for FIRST_HIGH_BIT.
2144 */
2145 if (xbe.get_button() > SunToolkit.MAX_BUTTONS_SUPPORTED) {
2146 return;
2147 }
2148 if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2149 grabLog.fine("{0}, when grabbed {1}, contains {2} ({3}, {4}, {5}x{6})",
2150 xbe, isGrabbed(), containsGlobal(xbe.get_x_root(), xbe.get_y_root()), getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight());
2151 }
2152 if (isGrabbed()) {
2153 // When window is grabbed, all events are dispatched to
2154 // it. Retarget them to the corresponding windows (notice
2155 // that XBaseWindow.dispatchEvent does the opposite
2156 // translation)
2157 XBaseWindow target = XToolkit.windowToXWindow(xbe.get_window());
2158 try {
2159 if (grabLog.isLoggable(PlatformLogger.Level.FINER)) {
2160 grabLog.finer(" - Grab event target {0} (press target {1})", target, pressTarget);
2161 }
2162 if (xbe.get_type() == XConstants.ButtonPress
2163 && xbe.get_button() == XConstants.buttons[0])
2164 {
2165 // need to keep it to retarget mouse release
2166 pressTarget = target;
2167 } else if (xbe.get_type() == XConstants.ButtonRelease
2168 && xbe.get_button() == XConstants.buttons[0]
2169 && pressTarget != target)
2170 {
2171 // during grab we do receive mouse release on different component (not on the source
2172 // of mouse press). So we need to retarget it.
2173 // see 6390326 for more information.
2174 target = pressTarget.isVisible() ? pressTarget : this;
2175 xbe.set_window(target.getWindow());
2176 Point localCoord = target.toLocal(xbe.get_x_root(), xbe.get_y_root());
2177 xbe.set_x(localCoord.x);
2178 xbe.set_y(localCoord.y);
2179 pressTarget = this;
2180 }
2181 if (target != null && target != getContentXWindow() && target != this) {
2182 target.dispatchEvent(xev);
2183 return;
2184 }
2185 } finally {
2186 if (target != null) {
2187 // Target is either us or our content window -
2188 // check that event is inside. 'Us' in case of
2189 // shell will mean that this will also filter out press on title
2190 if ((target == this || target == getContentXWindow()) && !containsGlobal(xbe.get_x_root(), xbe.get_y_root())) {
2191 // Outside this toplevel hierarchy
2192 // According to the specification of UngrabEvent, post it
2193 // when press occurs outside of the window and not on its owned windows
2194 if (xbe.get_type() == XConstants.ButtonPress) {
2195 if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2196 grabLog.fine("Generating UngrabEvent on {0} because not inside of shell", this);
2197 }
2198 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2199 return;
2200 }
2201 }
2202 // First, get the toplevel
2203 XWindowPeer toplevel = target.getToplevelXWindow();
2204 if (toplevel != null) {
2205 Window w = (Window)toplevel.target;
2206 while (w != null && toplevel != this && !(toplevel instanceof XDialogPeer)) {
2207 w = (Window) AWTAccessor.getComponentAccessor().getParent(w);
2208 if (w != null) {
2209 toplevel = (XWindowPeer) AWTAccessor.getComponentAccessor().getPeer(w);
2210 }
2211 }
2212 if (w == null || (w != this.target && w instanceof Dialog)) {
2213 // toplevel == null - outside of
2214 // hierarchy, toplevel is Dialog - should
2215 // send ungrab (but shouldn't for Window)
2216 if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2217 grabLog.fine("Generating UngrabEvent on {0} because hierarchy ended", this);
2218 }
2219 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2220 }
2221 } else {
2222 // toplevel is null - outside of hierarchy
2223 if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2224 grabLog.fine("Generating UngrabEvent on {0} because toplevel is null", this);
2225 }
2226 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2227 return;
2228 }
2229 } else {
2230 // target doesn't map to XAWT window - outside of hierarchy
2231 if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
2232 grabLog.fine("Generating UngrabEvent on because target is null {0}", this);
2233 }
2234 postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2235 return;
2236 }
2237 }
2238 }
2239 super.handleButtonPressRelease(xev);
2240 }
2241
2242 public void print(Graphics g) {
2243 // We assume we print the whole frame,
2244 // so we expect no clip was set previously
2245 Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
2246 if (shape != null) {
2247 g.setClip(shape);
2248 }
2249 super.print(g);
2250 }
2251
|