112 113 /* 114 * This constant defines icon size recommended for using. 115 * Apparently, we should use XGetIconSizes which should 116 * return icon sizes would be most appreciated by the WM. 117 * However, XGetIconSizes always returns 0 for some reason. 118 * So the constant has been introduced. 119 */ 120 private static final int PREFERRED_SIZE_FOR_ICON = 128; 121 122 /* 123 * Sometimes XChangeProperty(_NET_WM_ICON) doesn't work if 124 * image buffer is too large. This constant holds maximum 125 * length of buffer which can be used with _NET_WM_ICON hint. 126 * It holds int's value. 127 */ 128 private static final int MAXIMUM_BUFFER_LENGTH_NET_WM_ICON = (2<<15) - 1; 129 130 void preInit(XCreateWindowParams params) { 131 target = (Component)params.get(TARGET); 132 params.put(REPARENTED, 133 Boolean.valueOf(isOverrideRedirect() || isSimpleWindow())); 134 super.preInit(params); 135 params.putIfNull(BIT_GRAVITY, Integer.valueOf(XConstants.NorthWestGravity)); 136 137 long eventMask = 0; 138 if (params.containsKey(EVENT_MASK)) { 139 eventMask = ((Long)params.get(EVENT_MASK)); 140 } 141 eventMask |= XConstants.VisibilityChangeMask; 142 params.put(EVENT_MASK, eventMask); 143 144 XA_NET_WM_STATE = XAtom.get("_NET_WM_STATE"); 145 146 147 params.put(OVERRIDE_REDIRECT, Boolean.valueOf(isOverrideRedirect())); 148 149 SunToolkit.awtLock(); 150 try { 151 windows.add(this); 152 } finally { 153 SunToolkit.awtUnlock(); 500 // NOTE: This method may be called by privileged threads. 501 // DO NOT INVOKE CLIENT CODE ON THIS THREAD! 502 public void handleIconify() { 503 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_ICONIFIED)); 504 } 505 506 // NOTE: This method may be called by privileged threads. 507 // DO NOT INVOKE CLIENT CODE ON THIS THREAD! 508 public void handleDeiconify() { 509 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_DEICONIFIED)); 510 } 511 512 // NOTE: This method may be called by privileged threads. 513 // DO NOT INVOKE CLIENT CODE ON THIS THREAD! 514 public void handleStateChange(int oldState, int newState) { 515 postEvent(new WindowEvent((Window)target, 516 WindowEvent.WINDOW_STATE_CHANGED, 517 oldState, newState)); 518 } 519 520 /** 521 * DEPRECATED: Replaced by getInsets(). 522 */ 523 public Insets insets() { 524 return getInsets(); 525 } 526 527 boolean isAutoRequestFocus() { 528 if (XToolkit.isToolkitThread()) { 529 return WindowAccessor.isAutoRequestFocus((Window)target); 530 } else { 531 return ((Window)target).isAutoRequestFocus(); 532 } 533 } 534 535 /* 536 * Retrives real native focused window and converts it into Java peer. 537 */ 538 static XWindowPeer getNativeFocusedWindowPeer() { 539 XBaseWindow baseWindow = XToolkit.windowToXWindow(xGetInputFocus()); 540 return (baseWindow instanceof XWindowPeer) ? (XWindowPeer)baseWindow : 541 (baseWindow instanceof XFocusProxyWindow) ? 542 ((XFocusProxyWindow)baseWindow).getOwner() : null; 543 } 544 545 /* 546 * Retrives real native focused window and converts it into Java window. 697 public void displayChanged() { 698 executeDisplayChangedOnEDT(getGraphicsConfiguration()); 699 } 700 701 /** 702 * From the DisplayChangedListener interface; top-levels do not need 703 * to react to this event. 704 */ 705 public void paletteChanged() { 706 } 707 708 /* 709 * Overridden to check if we need to update our GraphicsDevice/Config 710 * Added for 4934052. 711 */ 712 @Override 713 public void handleConfigureNotifyEvent(XEvent xev) { 714 // TODO: We create an XConfigureEvent every time we override 715 // handleConfigureNotify() - too many! 716 XConfigureEvent xe = xev.get_xconfigure(); 717 checkIfOnNewScreen(new Rectangle(xe.get_x(), 718 xe.get_y(), 719 xe.get_width(), 720 xe.get_height())); 721 722 // Don't call super until we've handled a screen change. Otherwise 723 // there could be a race condition in which a ComponentListener could 724 // see the old screen. 725 super.handleConfigureNotifyEvent(xev); 726 repositionSecurityWarning(); 727 } 728 729 final void requestXFocus(long time) { 730 requestXFocus(time, true); 731 } 732 733 final void requestXFocus() { 734 requestXFocus(0, false); 735 } 736 1160 // if (ve.get_state() == XlibWrapper.VisibilityUnobscured) { 1161 // // raiseInputMethodWindow 1162 // } 1163 repositionSecurityWarning(); 1164 } 1165 1166 void handleRootPropertyNotify(XEvent xev) { 1167 XPropertyEvent ev = xev.get_xproperty(); 1168 if( mustControlStackPosition && 1169 ev.get_atom() == XAtom.get("_NET_CLIENT_LIST_STACKING").getAtom()){ 1170 // Restore stack order unhadled/spoiled by WM or some app (nautilus). 1171 // As of now, don't use any generic machinery: just 1172 // do toBack() again. 1173 if(isOverrideRedirect()) { 1174 toBack(); 1175 } 1176 } 1177 } 1178 1179 public void handleMapNotifyEvent(XEvent xev) { 1180 // See 6480534. 1181 isUnhiding |= isWMStateNetHidden(); 1182 1183 super.handleMapNotifyEvent(xev); 1184 if (!winAttr.initialFocus) { 1185 suppressWmTakeFocus(false); // restore the protocol. 1186 /* 1187 * For some reason, on Metacity, a frame/dialog being shown 1188 * without WM_TAKE_FOCUS protocol doesn't get moved to the front. 1189 * So, we do it evidently. 1190 */ 1191 XToolkit.awtLock(); 1192 try { 1193 XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow()); 1194 } finally { 1195 XToolkit.awtUnlock(); 1196 } 1197 } 1198 if (shouldFocusOnMapNotify()) { 1199 focusLog.fine("Automatically request focus on window"); 1200 requestInitialFocus(); 1201 } 1202 isUnhiding = false; 1203 isBeforeFirstMapNotify = false; 1204 updateAlwaysOnTop(); 1205 1206 synchronized (getStateLock()) { 1207 if (!isMapped) { 1208 isMapped = true; 1209 } 1210 } 1211 } 1212 1213 public void handleUnmapNotifyEvent(XEvent xev) { 1214 super.handleUnmapNotifyEvent(xev); 1215 1216 // On Metacity UnmapNotify comes before PropertyNotify (for _NET_WM_STATE_HIDDEN). 1217 // So we also check for the property later in MapNotify. See 6480534. 1218 isUnhiding |= isWMStateNetHidden(); 1219 1220 synchronized (getStateLock()) { 1221 if (isMapped) { 1222 isMapped = false; 1223 } 1224 } 1225 } 1226 1227 private boolean shouldFocusOnMapNotify() { 1228 boolean res = false; 1229 1230 if (isBeforeFirstMapNotify) { 1231 res = (winAttr.initialFocus || // Window.autoRequestFocus 1232 isFocusedWindowModalBlocker()); 1233 } else { 1280 } 1281 1282 boolean isWithdrawn() { 1283 return getWMState() == XUtilConstants.WithdrawnState; 1284 } 1285 1286 boolean hasDecorations(int decor) { 1287 if (!winAttr.nativeDecor) { 1288 return false; 1289 } 1290 else { 1291 int myDecor = winAttr.decorations; 1292 boolean hasBits = ((myDecor & decor) == decor); 1293 if ((myDecor & XWindowAttributesData.AWT_DECOR_ALL) != 0) 1294 return !hasBits; 1295 else 1296 return hasBits; 1297 } 1298 } 1299 1300 void setReparented(boolean newValue) { 1301 super.setReparented(newValue); 1302 XToolkit.awtLock(); 1303 try { 1304 if (isReparented() && delayedModalBlocking) { 1305 addToTransientFors((XDialogPeer) ComponentAccessor.getPeer(modalBlocker)); 1306 delayedModalBlocking = false; 1307 } 1308 } finally { 1309 XToolkit.awtUnlock(); 1310 } 1311 } 1312 1313 /* 1314 * Returns a Vector of all Java top-level windows, 1315 * sorted by their current Z-order 1316 */ 1317 static Vector<XWindowPeer> collectJavaToplevels() { 1318 Vector<XWindowPeer> javaToplevels = new Vector<XWindowPeer>(); 1319 Vector<Long> v = new Vector<Long>(); 1320 X11GraphicsEnvironment ge = 1321 (X11GraphicsEnvironment)GraphicsEnvironment.getLocalGraphicsEnvironment(); 1322 GraphicsDevice[] gds = ge.getScreenDevices(); 1323 if (!ge.runningXinerama() && (gds.length > 1)) { 1324 for (GraphicsDevice gd : gds) { 1374 } 1375 } 1376 return javaToplevels; 1377 } 1378 1379 public void setModalBlocked(Dialog d, boolean blocked) { 1380 setModalBlocked(d, blocked, null); 1381 } 1382 public void setModalBlocked(Dialog d, boolean blocked, 1383 Vector<XWindowPeer> javaToplevels) 1384 { 1385 XToolkit.awtLock(); 1386 try { 1387 // State lock should always be after awtLock 1388 synchronized(getStateLock()) { 1389 XDialogPeer blockerPeer = (XDialogPeer) ComponentAccessor.getPeer(d); 1390 if (blocked) { 1391 log.log(Level.FINE, "{0} is blocked by {1}", new Object[] { this, blockerPeer}); 1392 modalBlocker = d; 1393 1394 if (isReparented() || XWM.isNonReparentingWM()) { 1395 addToTransientFors(blockerPeer, javaToplevels); 1396 } else { 1397 delayedModalBlocking = true; 1398 } 1399 } else { 1400 if (d != modalBlocker) { 1401 throw new IllegalStateException("Trying to unblock window blocked by another dialog"); 1402 } 1403 modalBlocker = null; 1404 1405 if (isReparented() || XWM.isNonReparentingWM()) { 1406 removeFromTransientFors(); 1407 } else { 1408 delayedModalBlocking = false; 1409 } 1410 } 1411 1412 updateTransientFor(); 1413 } 1414 } finally { 1415 XToolkit.awtUnlock(); 1416 } 1417 } 1418 1419 /* 1420 * Sets the TRANSIENT_FOR hint to the given top-level window. This 1421 * method is used when a window is modal blocked/unblocked or 1422 * changed its state from/to NormalState to/from other states. 1423 * If window or transientForWindow are embedded frames, the containing 1424 * top-level windows are used. 1425 * | 112 113 /* 114 * This constant defines icon size recommended for using. 115 * Apparently, we should use XGetIconSizes which should 116 * return icon sizes would be most appreciated by the WM. 117 * However, XGetIconSizes always returns 0 for some reason. 118 * So the constant has been introduced. 119 */ 120 private static final int PREFERRED_SIZE_FOR_ICON = 128; 121 122 /* 123 * Sometimes XChangeProperty(_NET_WM_ICON) doesn't work if 124 * image buffer is too large. This constant holds maximum 125 * length of buffer which can be used with _NET_WM_ICON hint. 126 * It holds int's value. 127 */ 128 private static final int MAXIMUM_BUFFER_LENGTH_NET_WM_ICON = (2<<15) - 1; 129 130 void preInit(XCreateWindowParams params) { 131 target = (Component)params.get(TARGET); 132 super.preInit(params); 133 params.putIfNull(BIT_GRAVITY, Integer.valueOf(XConstants.NorthWestGravity)); 134 135 long eventMask = 0; 136 if (params.containsKey(EVENT_MASK)) { 137 eventMask = ((Long)params.get(EVENT_MASK)); 138 } 139 eventMask |= XConstants.VisibilityChangeMask; 140 params.put(EVENT_MASK, eventMask); 141 142 XA_NET_WM_STATE = XAtom.get("_NET_WM_STATE"); 143 144 145 params.put(OVERRIDE_REDIRECT, Boolean.valueOf(isOverrideRedirect())); 146 147 SunToolkit.awtLock(); 148 try { 149 windows.add(this); 150 } finally { 151 SunToolkit.awtUnlock(); 498 // NOTE: This method may be called by privileged threads. 499 // DO NOT INVOKE CLIENT CODE ON THIS THREAD! 500 public void handleIconify() { 501 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_ICONIFIED)); 502 } 503 504 // NOTE: This method may be called by privileged threads. 505 // DO NOT INVOKE CLIENT CODE ON THIS THREAD! 506 public void handleDeiconify() { 507 postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_DEICONIFIED)); 508 } 509 510 // NOTE: This method may be called by privileged threads. 511 // DO NOT INVOKE CLIENT CODE ON THIS THREAD! 512 public void handleStateChange(int oldState, int newState) { 513 postEvent(new WindowEvent((Window)target, 514 WindowEvent.WINDOW_STATE_CHANGED, 515 oldState, newState)); 516 } 517 518 boolean isAutoRequestFocus() { 519 if (XToolkit.isToolkitThread()) { 520 return WindowAccessor.isAutoRequestFocus((Window)target); 521 } else { 522 return ((Window)target).isAutoRequestFocus(); 523 } 524 } 525 526 /* 527 * Retrives real native focused window and converts it into Java peer. 528 */ 529 static XWindowPeer getNativeFocusedWindowPeer() { 530 XBaseWindow baseWindow = XToolkit.windowToXWindow(xGetInputFocus()); 531 return (baseWindow instanceof XWindowPeer) ? (XWindowPeer)baseWindow : 532 (baseWindow instanceof XFocusProxyWindow) ? 533 ((XFocusProxyWindow)baseWindow).getOwner() : null; 534 } 535 536 /* 537 * Retrives real native focused window and converts it into Java window. 688 public void displayChanged() { 689 executeDisplayChangedOnEDT(getGraphicsConfiguration()); 690 } 691 692 /** 693 * From the DisplayChangedListener interface; top-levels do not need 694 * to react to this event. 695 */ 696 public void paletteChanged() { 697 } 698 699 /* 700 * Overridden to check if we need to update our GraphicsDevice/Config 701 * Added for 4934052. 702 */ 703 @Override 704 public void handleConfigureNotifyEvent(XEvent xev) { 705 // TODO: We create an XConfigureEvent every time we override 706 // handleConfigureNotify() - too many! 707 XConfigureEvent xe = xev.get_xconfigure(); 708 if (xe.get_window() != getWindow()) { 709 return; 710 } 711 712 checkIfOnNewScreen(new Rectangle(xe.get_x(), 713 xe.get_y(), 714 xe.get_width(), 715 xe.get_height())); 716 717 // Don't call super until we've handled a screen change. Otherwise 718 // there could be a race condition in which a ComponentListener could 719 // see the old screen. 720 super.handleConfigureNotifyEvent(xev); 721 repositionSecurityWarning(); 722 } 723 724 final void requestXFocus(long time) { 725 requestXFocus(time, true); 726 } 727 728 final void requestXFocus() { 729 requestXFocus(0, false); 730 } 731 1155 // if (ve.get_state() == XlibWrapper.VisibilityUnobscured) { 1156 // // raiseInputMethodWindow 1157 // } 1158 repositionSecurityWarning(); 1159 } 1160 1161 void handleRootPropertyNotify(XEvent xev) { 1162 XPropertyEvent ev = xev.get_xproperty(); 1163 if( mustControlStackPosition && 1164 ev.get_atom() == XAtom.get("_NET_CLIENT_LIST_STACKING").getAtom()){ 1165 // Restore stack order unhadled/spoiled by WM or some app (nautilus). 1166 // As of now, don't use any generic machinery: just 1167 // do toBack() again. 1168 if(isOverrideRedirect()) { 1169 toBack(); 1170 } 1171 } 1172 } 1173 1174 public void handleMapNotifyEvent(XEvent xev) { 1175 if (xev.get_xany().get_window() != getWindow()) { 1176 return; 1177 } 1178 1179 // See 6480534. 1180 isUnhiding |= isWMStateNetHidden(); 1181 1182 super.handleMapNotifyEvent(xev); 1183 if (!winAttr.initialFocus) { 1184 suppressWmTakeFocus(false); // restore the protocol. 1185 /* 1186 * For some reason, on Metacity, a frame/dialog being shown 1187 * without WM_TAKE_FOCUS protocol doesn't get moved to the front. 1188 * So, we do it evidently. 1189 */ 1190 XToolkit.awtLock(); 1191 try { 1192 XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow()); 1193 } finally { 1194 XToolkit.awtUnlock(); 1195 } 1196 } 1197 if (shouldFocusOnMapNotify()) { 1198 focusLog.fine("Automatically request focus on window"); 1199 requestInitialFocus(); 1200 } 1201 isUnhiding = false; 1202 isBeforeFirstMapNotify = false; 1203 updateAlwaysOnTop(); 1204 1205 synchronized (getStateLock()) { 1206 if (!isMapped) { 1207 isMapped = true; 1208 } 1209 } 1210 } 1211 1212 public void handleUnmapNotifyEvent(XEvent xev) { 1213 if (xev.get_xany().get_window() != getWindow()) { 1214 return; 1215 } 1216 super.handleUnmapNotifyEvent(xev); 1217 1218 // On Metacity UnmapNotify comes before PropertyNotify (for _NET_WM_STATE_HIDDEN). 1219 // So we also check for the property later in MapNotify. See 6480534. 1220 isUnhiding |= isWMStateNetHidden(); 1221 1222 synchronized (getStateLock()) { 1223 if (isMapped) { 1224 isMapped = false; 1225 } 1226 } 1227 } 1228 1229 private boolean shouldFocusOnMapNotify() { 1230 boolean res = false; 1231 1232 if (isBeforeFirstMapNotify) { 1233 res = (winAttr.initialFocus || // Window.autoRequestFocus 1234 isFocusedWindowModalBlocker()); 1235 } else { 1282 } 1283 1284 boolean isWithdrawn() { 1285 return getWMState() == XUtilConstants.WithdrawnState; 1286 } 1287 1288 boolean hasDecorations(int decor) { 1289 if (!winAttr.nativeDecor) { 1290 return false; 1291 } 1292 else { 1293 int myDecor = winAttr.decorations; 1294 boolean hasBits = ((myDecor & decor) == decor); 1295 if ((myDecor & XWindowAttributesData.AWT_DECOR_ALL) != 0) 1296 return !hasBits; 1297 else 1298 return hasBits; 1299 } 1300 } 1301 1302 @Override 1303 public boolean mayBeReparented() { 1304 return 1305 !isOverrideRedirect() && 1306 !isSimpleWindow() && 1307 super.mayBeReparented(); 1308 } 1309 1310 @Override 1311 public void setNativeParent(long parent) { 1312 super.setNativeParent(parent); 1313 XToolkit.awtLock(); 1314 try { 1315 if (!mayBeReparented() && delayedModalBlocking) { 1316 addToTransientFors((XDialogPeer) ComponentAccessor.getPeer(modalBlocker)); 1317 delayedModalBlocking = false; 1318 } 1319 } finally { 1320 XToolkit.awtUnlock(); 1321 } 1322 } 1323 1324 /* 1325 * Returns a Vector of all Java top-level windows, 1326 * sorted by their current Z-order 1327 */ 1328 static Vector<XWindowPeer> collectJavaToplevels() { 1329 Vector<XWindowPeer> javaToplevels = new Vector<XWindowPeer>(); 1330 Vector<Long> v = new Vector<Long>(); 1331 X11GraphicsEnvironment ge = 1332 (X11GraphicsEnvironment)GraphicsEnvironment.getLocalGraphicsEnvironment(); 1333 GraphicsDevice[] gds = ge.getScreenDevices(); 1334 if (!ge.runningXinerama() && (gds.length > 1)) { 1335 for (GraphicsDevice gd : gds) { 1385 } 1386 } 1387 return javaToplevels; 1388 } 1389 1390 public void setModalBlocked(Dialog d, boolean blocked) { 1391 setModalBlocked(d, blocked, null); 1392 } 1393 public void setModalBlocked(Dialog d, boolean blocked, 1394 Vector<XWindowPeer> javaToplevels) 1395 { 1396 XToolkit.awtLock(); 1397 try { 1398 // State lock should always be after awtLock 1399 synchronized(getStateLock()) { 1400 XDialogPeer blockerPeer = (XDialogPeer) ComponentAccessor.getPeer(d); 1401 if (blocked) { 1402 log.log(Level.FINE, "{0} is blocked by {1}", new Object[] { this, blockerPeer}); 1403 modalBlocker = d; 1404 1405 if (!mayBeReparented()) { 1406 addToTransientFors(blockerPeer, javaToplevels); 1407 } else { 1408 delayedModalBlocking = true; 1409 } 1410 } else { 1411 if (d != modalBlocker) { 1412 throw new IllegalStateException("Trying to unblock window blocked by another dialog"); 1413 } 1414 modalBlocker = null; 1415 1416 if (!mayBeReparented()) { 1417 removeFromTransientFors(); 1418 } else { 1419 delayedModalBlocking = false; 1420 } 1421 } 1422 1423 updateTransientFor(); 1424 } 1425 } finally { 1426 XToolkit.awtUnlock(); 1427 } 1428 } 1429 1430 /* 1431 * Sets the TRANSIENT_FOR hint to the given top-level window. This 1432 * method is used when a window is modal blocked/unblocked or 1433 * changed its state from/to NormalState to/from other states. 1434 * If window or transientForWindow are embedded frames, the containing 1435 * top-level windows are used. 1436 * |