< prev index next >

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

Print this page




  69 
  70     // should be synchronized on awtLock
  71     private static Set<XWindowPeer> windows = new HashSet<XWindowPeer>();
  72 
  73 
  74     private boolean cachedFocusableWindow;
  75     XWarningWindow warningWindow;
  76 
  77     private boolean alwaysOnTop;
  78     private boolean locationByPlatform;
  79 
  80     Dialog modalBlocker;
  81     boolean delayedModalBlocking = false;
  82     Dimension targetMinimumSize = null;
  83 
  84     private XWindowPeer ownerPeer;
  85 
  86     // used for modal blocking to keep existing z-order
  87     protected XWindowPeer prevTransientFor, nextTransientFor;
  88     // value of WM_TRANSIENT_FOR hint set on this window
  89     private XWindowPeer curRealTransientFor;
  90 
  91     private boolean grab = false; // Whether to do a grab during showing
  92 
  93     private boolean isMapped = false; // Is this window mapped or not
  94     private boolean mustControlStackPosition = false; // Am override-redirect not on top
  95     private XEventDispatcher rootPropertyEventDispatcher = null;
  96 
  97     private static final AtomicBoolean isStartupNotificationRemoved = new AtomicBoolean();
  98 
  99     /*
 100      * Focus related flags
 101      */
 102     private boolean isUnhiding = false;             // Is the window unhiding.
 103     private boolean isBeforeFirstMapNotify = false; // Is the window (being shown) between
 104                                                     //    setVisible(true) & handleMapNotify().
 105 
 106     /**
 107      * The type of the window.
 108      *
 109      * The type is supposed to be immutable while the peer object exists.


1045 
1046         return ret;
1047     }
1048 
1049     private static boolean isDesktopWindow( long wi ) {
1050         return XWM.getWM().isDesktopWindow( wi );
1051     }
1052 
1053     private void updateAlwaysOnTop() {
1054         if (log.isLoggable(PlatformLogger.Level.FINE)) {
1055             log.fine("Promoting always-on-top state {0}", Boolean.valueOf(alwaysOnTop));
1056         }
1057         XWM.getWM().setLayer(this,
1058                              alwaysOnTop ?
1059                              XLayerProtocol.LAYER_ALWAYS_ON_TOP :
1060                              XLayerProtocol.LAYER_NORMAL);
1061     }
1062 
1063     public void updateAlwaysOnTopState() {
1064         this.alwaysOnTop = ((Window) this.target).isAlwaysOnTop();










1065         updateAlwaysOnTop();
1066     }
1067 
1068     boolean isLocationByPlatform() {
1069         return locationByPlatform;
1070     }
1071 
1072     private void promoteDefaultPosition() {
1073         this.locationByPlatform = ((Window)target).isLocationByPlatform();
1074         if (locationByPlatform) {
1075             XToolkit.awtLock();
1076             try {
1077                 Rectangle bounds = getBounds();
1078                 XSizeHints hints = getHints();
1079                 setSizeHints(hints.get_flags() & ~(XUtilConstants.USPosition | XUtilConstants.PPosition),
1080                              bounds.x, bounds.y, bounds.width, bounds.height);
1081             } finally {
1082                 XToolkit.awtUnlock();
1083             }
1084         }


1088         if (!isVisible() && vis) {
1089             isBeforeFirstMapNotify = true;
1090             winAttr.initialFocus = isAutoRequestFocus();
1091             if (!winAttr.initialFocus) {
1092                 /*
1093                  * It's easier and safer to temporary suppress WM_TAKE_FOCUS
1094                  * protocol itself than to ignore WM_TAKE_FOCUS client message.
1095                  * Because we will have to make the difference between
1096                  * the message come after showing and the message come after
1097                  * activation. Also, on Metacity, for some reason, we have _two_
1098                  * WM_TAKE_FOCUS client messages when showing a frame/dialog.
1099                  */
1100                 suppressWmTakeFocus(true);
1101             }
1102         }
1103         updateFocusability();
1104         promoteDefaultPosition();
1105         if (!vis && warningWindow != null) {
1106             warningWindow.setSecurityWarningVisible(false, false);
1107         }

1108         super.setVisible(vis);



















1109         if (!vis && !isWithdrawn()) {
1110             // ICCCM, 4.1.4. Changing Window State:
1111             // "Iconic -> Withdrawn - The client should unmap the window and follow it
1112             // with a synthetic UnmapNotify event as described later in this section."
1113             // The same is true for Normal -> Withdrawn
1114             XToolkit.awtLock();
1115             try {
1116                 XUnmapEvent unmap = new XUnmapEvent();
1117                 unmap.set_window(window);
1118                 unmap.set_event(XToolkit.getDefaultRootWindow());
1119                 unmap.set_type(XConstants.UnmapNotify);
1120                 unmap.set_from_configure(false);
1121                 XlibWrapper.XSendEvent(XToolkit.getDisplay(), XToolkit.getDefaultRootWindow(),
1122                         false, XConstants.SubstructureNotifyMask | XConstants.SubstructureRedirectMask,
1123                         unmap.pData);
1124                 unmap.dispose();
1125             }
1126             finally {
1127                 XToolkit.awtUnlock();
1128             }


1617      *
1618      * @param window specifies the top-level window that the hint
1619      *  is to be set to
1620      * @param transientForWindow the top-level window
1621      * @param updateChain specifies if next/prevTransientFor fields are
1622      *  to be updated
1623      * @param allStates if set to <code>true</code> then TRANSIENT_FOR hint
1624      *  is set regardless of the state of window and transientForWindow,
1625      *  otherwise it is set only if both are in the same state
1626      */
1627     static void setToplevelTransientFor(XWindowPeer window, XWindowPeer transientForWindow,
1628                                                 boolean updateChain, boolean allStates)
1629     {
1630         if ((window == null) || (transientForWindow == null)) {
1631             return;
1632         }
1633         if (updateChain) {
1634             window.prevTransientFor = transientForWindow;
1635             transientForWindow.nextTransientFor = window;
1636         }
1637         if (window.curRealTransientFor == transientForWindow) {
1638             return;
1639         }
1640         if (!allStates && (window.getWMState() != transientForWindow.getWMState())) {
1641             return;
1642         }
1643         if (window.getScreenNumber() != transientForWindow.getScreenNumber()) {
1644             return;
1645         }
1646         long bpw = window.getWindow();
1647         while (!XlibUtil.isToplevelWindow(bpw) && !XlibUtil.isXAWTToplevelWindow(bpw)) {
1648             bpw = XlibUtil.getParentWindow(bpw);
1649         }
1650         long tpw = transientForWindow.getWindow();
1651         while (!XlibUtil.isToplevelWindow(tpw) && !XlibUtil.isXAWTToplevelWindow(tpw)) {


1652             tpw = XlibUtil.getParentWindow(tpw);

1653         }
1654         XlibWrapper.XSetTransientFor(XToolkit.getDisplay(), bpw, tpw);
1655         window.curRealTransientFor = transientForWindow;
1656     }
1657 
1658     /*
1659      * This method does nothing if this window is not blocked by any modal dialog.
1660      * For modal blocked windows this method looks up for the nearest
1661      *  prevTransiendFor window that is in the same state (Normal/Iconified/Withdrawn)
1662      *  as this one and makes this window transient for it. The same operation is
1663      *  performed for nextTransientFor window.
1664      * Values of prevTransientFor and nextTransientFor fields are not changed.
1665      */
1666     void updateTransientFor() {
1667         int state = getWMState();
1668         XWindowPeer p = prevTransientFor;
1669         while ((p != null) && ((p.getWMState() != state) || (p.getScreenNumber() != getScreenNumber()))) {
1670             p = p.prevTransientFor;
1671         }
1672         if (p != null) {
1673             setToplevelTransientFor(this, p, false, false);
1674         } else {
1675             restoreTransientFor(this);


1929     }
1930 
1931     // This method is to be overriden in XDecoratedPeer.
1932     void setActualFocusedWindow(XWindowPeer actualFocusedWindow) {
1933     }
1934 
1935     /**
1936      * Applies the current window type.
1937      */
1938     private void applyWindowType() {
1939         XNETProtocol protocol = XWM.getWM().getNETProtocol();
1940         if (protocol == null) {
1941             return;
1942         }
1943 
1944         XAtom typeAtom = null;
1945 
1946         switch (getWindowType())
1947         {
1948             case NORMAL:
1949                 typeAtom = (ownerPeer == null) ?
1950                                protocol.XA_NET_WM_WINDOW_TYPE_NORMAL :
1951                                protocol.XA_NET_WM_WINDOW_TYPE_DIALOG;
1952                 break;
1953             case UTILITY:
1954                 typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_UTILITY;
1955                 break;
1956             case POPUP:
1957                 typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_POPUP_MENU;
1958                 break;
1959         }
1960 
1961         if (typeAtom != null) {
1962             XAtomList wtype = new XAtomList();
1963             wtype.add(typeAtom);
1964             protocol.XA_NET_WM_WINDOW_TYPE.
1965                 setAtomListProperty(getWindow(), wtype);
1966         } else {
1967             protocol.XA_NET_WM_WINDOW_TYPE.
1968                 DeleteProperty(getWindow());
1969         }




  69 
  70     // should be synchronized on awtLock
  71     private static Set<XWindowPeer> windows = new HashSet<XWindowPeer>();
  72 
  73 
  74     private boolean cachedFocusableWindow;
  75     XWarningWindow warningWindow;
  76 
  77     private boolean alwaysOnTop;
  78     private boolean locationByPlatform;
  79 
  80     Dialog modalBlocker;
  81     boolean delayedModalBlocking = false;
  82     Dimension targetMinimumSize = null;
  83 
  84     private XWindowPeer ownerPeer;
  85 
  86     // used for modal blocking to keep existing z-order
  87     protected XWindowPeer prevTransientFor, nextTransientFor;
  88     // value of WM_TRANSIENT_FOR hint set on this window
  89     private XBaseWindow curRealTransientFor;
  90 
  91     private boolean grab = false; // Whether to do a grab during showing
  92 
  93     private boolean isMapped = false; // Is this window mapped or not
  94     private boolean mustControlStackPosition = false; // Am override-redirect not on top
  95     private XEventDispatcher rootPropertyEventDispatcher = null;
  96 
  97     private static final AtomicBoolean isStartupNotificationRemoved = new AtomicBoolean();
  98 
  99     /*
 100      * Focus related flags
 101      */
 102     private boolean isUnhiding = false;             // Is the window unhiding.
 103     private boolean isBeforeFirstMapNotify = false; // Is the window (being shown) between
 104                                                     //    setVisible(true) & handleMapNotify().
 105 
 106     /**
 107      * The type of the window.
 108      *
 109      * The type is supposed to be immutable while the peer object exists.


1045 
1046         return ret;
1047     }
1048 
1049     private static boolean isDesktopWindow( long wi ) {
1050         return XWM.getWM().isDesktopWindow( wi );
1051     }
1052 
1053     private void updateAlwaysOnTop() {
1054         if (log.isLoggable(PlatformLogger.Level.FINE)) {
1055             log.fine("Promoting always-on-top state {0}", Boolean.valueOf(alwaysOnTop));
1056         }
1057         XWM.getWM().setLayer(this,
1058                 alwaysOnTop ?
1059                         XLayerProtocol.LAYER_ALWAYS_ON_TOP :
1060                         XLayerProtocol.LAYER_NORMAL);
1061     }
1062 
1063     public void updateAlwaysOnTopState() {
1064         this.alwaysOnTop = ((Window) this.target).isAlwaysOnTop();
1065         if (ownerPeer != null) {
1066             XToolkit.awtLock();
1067             try {
1068                 restoreTransientFor(this);
1069                 applyWindowType();
1070             }
1071             finally {
1072                 XToolkit.awtUnlock();
1073             }
1074         }
1075         updateAlwaysOnTop();
1076     }
1077 
1078     boolean isLocationByPlatform() {
1079         return locationByPlatform;
1080     }
1081 
1082     private void promoteDefaultPosition() {
1083         this.locationByPlatform = ((Window)target).isLocationByPlatform();
1084         if (locationByPlatform) {
1085             XToolkit.awtLock();
1086             try {
1087                 Rectangle bounds = getBounds();
1088                 XSizeHints hints = getHints();
1089                 setSizeHints(hints.get_flags() & ~(XUtilConstants.USPosition | XUtilConstants.PPosition),
1090                              bounds.x, bounds.y, bounds.width, bounds.height);
1091             } finally {
1092                 XToolkit.awtUnlock();
1093             }
1094         }


1098         if (!isVisible() && vis) {
1099             isBeforeFirstMapNotify = true;
1100             winAttr.initialFocus = isAutoRequestFocus();
1101             if (!winAttr.initialFocus) {
1102                 /*
1103                  * It's easier and safer to temporary suppress WM_TAKE_FOCUS
1104                  * protocol itself than to ignore WM_TAKE_FOCUS client message.
1105                  * Because we will have to make the difference between
1106                  * the message come after showing and the message come after
1107                  * activation. Also, on Metacity, for some reason, we have _two_
1108                  * WM_TAKE_FOCUS client messages when showing a frame/dialog.
1109                  */
1110                 suppressWmTakeFocus(true);
1111             }
1112         }
1113         updateFocusability();
1114         promoteDefaultPosition();
1115         if (!vis && warningWindow != null) {
1116             warningWindow.setSecurityWarningVisible(false, false);
1117         }
1118         boolean refreshChildsTransientFor = isVisible() != vis;
1119         super.setVisible(vis);
1120         if (refreshChildsTransientFor) {
1121             for (Window child : ((Window) target).getOwnedWindows()) {
1122                 XToolkit.awtLock();
1123                 try {
1124                     if(!child.isLightweight() && child.isVisible()) {
1125                         ComponentPeer childPeer = AWTAccessor.
1126                                 getComponentAccessor().getPeer(child);
1127                         if(childPeer instanceof XWindowPeer) {
1128                             XWindowPeer windowPeer = (XWindowPeer) childPeer;
1129                             restoreTransientFor(windowPeer);
1130                             windowPeer.applyWindowType();
1131                         }
1132                     }
1133                 }
1134                 finally {
1135                     XToolkit.awtUnlock();
1136                 }
1137             }
1138         }
1139         if (!vis && !isWithdrawn()) {
1140             // ICCCM, 4.1.4. Changing Window State:
1141             // "Iconic -> Withdrawn - The client should unmap the window and follow it
1142             // with a synthetic UnmapNotify event as described later in this section."
1143             // The same is true for Normal -> Withdrawn
1144             XToolkit.awtLock();
1145             try {
1146                 XUnmapEvent unmap = new XUnmapEvent();
1147                 unmap.set_window(window);
1148                 unmap.set_event(XToolkit.getDefaultRootWindow());
1149                 unmap.set_type(XConstants.UnmapNotify);
1150                 unmap.set_from_configure(false);
1151                 XlibWrapper.XSendEvent(XToolkit.getDisplay(), XToolkit.getDefaultRootWindow(),
1152                         false, XConstants.SubstructureNotifyMask | XConstants.SubstructureRedirectMask,
1153                         unmap.pData);
1154                 unmap.dispose();
1155             }
1156             finally {
1157                 XToolkit.awtUnlock();
1158             }


1647      *
1648      * @param window specifies the top-level window that the hint
1649      *  is to be set to
1650      * @param transientForWindow the top-level window
1651      * @param updateChain specifies if next/prevTransientFor fields are
1652      *  to be updated
1653      * @param allStates if set to <code>true</code> then TRANSIENT_FOR hint
1654      *  is set regardless of the state of window and transientForWindow,
1655      *  otherwise it is set only if both are in the same state
1656      */
1657     static void setToplevelTransientFor(XWindowPeer window, XWindowPeer transientForWindow,
1658                                                 boolean updateChain, boolean allStates)
1659     {
1660         if ((window == null) || (transientForWindow == null)) {
1661             return;
1662         }
1663         if (updateChain) {
1664             window.prevTransientFor = transientForWindow;
1665             transientForWindow.nextTransientFor = window;
1666         }



1667         if (!allStates && (window.getWMState() != transientForWindow.getWMState())) {
1668             return;
1669         }
1670         if (window.getScreenNumber() != transientForWindow.getScreenNumber()) {
1671             return;
1672         }
1673         long bpw = window.getWindow();
1674         while (!XlibUtil.isToplevelWindow(bpw) && !XlibUtil.isXAWTToplevelWindow(bpw)) {
1675             bpw = XlibUtil.getParentWindow(bpw);
1676         }
1677         long tpw = transientForWindow.getWindow();
1678         XBaseWindow parent = transientForWindow;
1679         while (tpw != 0 && ((!XlibUtil.isToplevelWindow(tpw) &&
1680                 !XlibUtil.isXAWTToplevelWindow(tpw)) || !parent.isVisible())) {
1681             tpw = XlibUtil.getParentWindow(tpw);
1682             parent = XToolkit.windowToXWindow(tpw);
1683         }
1684         XlibWrapper.XSetTransientFor(XToolkit.getDisplay(), bpw, tpw);
1685         window.curRealTransientFor = parent;
1686     }
1687 
1688     /*
1689      * This method does nothing if this window is not blocked by any modal dialog.
1690      * For modal blocked windows this method looks up for the nearest
1691      *  prevTransiendFor window that is in the same state (Normal/Iconified/Withdrawn)
1692      *  as this one and makes this window transient for it. The same operation is
1693      *  performed for nextTransientFor window.
1694      * Values of prevTransientFor and nextTransientFor fields are not changed.
1695      */
1696     void updateTransientFor() {
1697         int state = getWMState();
1698         XWindowPeer p = prevTransientFor;
1699         while ((p != null) && ((p.getWMState() != state) || (p.getScreenNumber() != getScreenNumber()))) {
1700             p = p.prevTransientFor;
1701         }
1702         if (p != null) {
1703             setToplevelTransientFor(this, p, false, false);
1704         } else {
1705             restoreTransientFor(this);


1959     }
1960 
1961     // This method is to be overriden in XDecoratedPeer.
1962     void setActualFocusedWindow(XWindowPeer actualFocusedWindow) {
1963     }
1964 
1965     /**
1966      * Applies the current window type.
1967      */
1968     private void applyWindowType() {
1969         XNETProtocol protocol = XWM.getWM().getNETProtocol();
1970         if (protocol == null) {
1971             return;
1972         }
1973 
1974         XAtom typeAtom = null;
1975 
1976         switch (getWindowType())
1977         {
1978             case NORMAL:
1979                 typeAtom = curRealTransientFor == null ?
1980                                protocol.XA_NET_WM_WINDOW_TYPE_NORMAL :
1981                                protocol.XA_NET_WM_WINDOW_TYPE_DIALOG;
1982                 break;
1983             case UTILITY:
1984                 typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_UTILITY;
1985                 break;
1986             case POPUP:
1987                 typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_POPUP_MENU;
1988                 break;
1989         }
1990 
1991         if (typeAtom != null) {
1992             XAtomList wtype = new XAtomList();
1993             wtype.add(typeAtom);
1994             protocol.XA_NET_WM_WINDOW_TYPE.
1995                 setAtomListProperty(getWindow(), wtype);
1996         } else {
1997             protocol.XA_NET_WM_WINDOW_TYPE.
1998                 DeleteProperty(getWindow());
1999         }


< prev index next >