SUGGESTED FIX
--- old/src/solaris/classes/sun/awt/X11/XWarningWindow.java 2008-12-04 19:07:27.000000000 +0300
+++ new/src/solaris/classes/sun/awt/X11/XWarningWindow.java 2008-12-04 19:07:27.000000000 +0300
@@ -246,6 +246,54 @@
return true;
}
+ /** Send a synthetic UnmapNotify in order to withdraw the window.
+ */
+ private void withdraw() {
+ XEvent req = new XEvent();
+ try {
+ long root;
+ XToolkit.awtLock();
+ try {
+ root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
+ }
+ finally {
+ XToolkit.awtUnlock();
+ }
+
+ req.set_type(UnmapNotify);
+
+ XUnmapEvent umev = req.get_xunmap();
+
+ umev.set_event(root);
+ umev.set_window(getWindow());
+ umev.set_from_configure(false);
+
+ XToolkit.awtLock();
+ try {
+ XlibWrapper.XSendEvent(XToolkit.getDisplay(),
+ root,
+ false,
+ XlibWrapper.SubstructureRedirectMask | XlibWrapper.SubstructureNotifyMask,
+ req.pData);
+ }
+ finally {
+ XToolkit.awtUnlock();
+ }
+ } finally {
+ req.dispose();
+ }
+ }
+
+ @Override
+ protected void stateChanged(long time, int oldState, int newState) {
+ if (newState == XlibWrapper.IconicState) {
+ withdraw();
+
+ // To update the local copy of the 'visible' flag in XBaseWindow
+ super.xSetVisible(false);
+ }
+ }
+
@Override
protected void setMouseAbove(boolean above) {
super.setMouseAbove(above);
@@ -271,34 +319,6 @@
}
}
- private XAtom XA_WM_CHANGE_STATE = XAtom.get("WM_CHANGE_STATE");
-
- private void deiconify() {
- XClientMessageEvent req = new XClientMessageEvent();
- try {
- req.set_type((int)XlibWrapper.ClientMessage);
- req.set_window(getWindow());
- req.set_message_type(XA_WM_CHANGE_STATE.getAtom());
- req.set_format(32);
- req.set_data(0, (int)XlibWrapper.NormalState);
- req.set_data(1, 0);
- req.set_data(2, 0);
- XToolkit.awtLock();
- try {
- XlibWrapper.XSendEvent(XToolkit.getDisplay(),
- XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()),
- false,
- XlibWrapper.SubstructureRedirectMask | XlibWrapper.SubstructureNotifyMask,
- req.pData);
- }
- finally {
- XToolkit.awtUnlock();
- }
- } finally {
- req.dispose();
- }
- }
-
@Override
public void xSetVisible(boolean visible) {
super.xSetVisible(visible);
@@ -306,10 +326,6 @@
// The _NET_WM_STATE_SKIP_TASKBAR got reset upon hiding/showing,
// so we request it every time whenever we change the visibility.
requestNoTaskbar();
-
- // This is a "reverse" operation of XIconifyWindow() in case the
- // waring window was iconified by the window manager.
- deiconify();
}
private final Runnable hidingTask = new Runnable() {
--- old/src/solaris/classes/sun/awt/X11/XWindow.java 2008-12-04 19:07:27.000000000 +0300
+++ new/src/solaris/classes/sun/awt/X11/XWindow.java 2008-12-04 19:07:27.000000000 +0300
@@ -78,6 +78,9 @@
protected static XAtom wm_protocols;
protected static XAtom wm_delete_window;
protected static XAtom wm_take_focus;
+
+ private boolean stateChanged; // Indicates whether the value on savedState is valid
+ private int savedState; // Holds last known state of the top-level window
XWindowAttributesData winAttr;
@@ -204,6 +207,7 @@
XToolkit.awtUnlock();
}
winAttr = new XWindowAttributesData();
+ savedState = WithdrawnState;
}
void postInit(XCreateWindowParams params) {
@@ -1139,6 +1143,55 @@
}
+ /*
+ * XmNiconic and Map/UnmapNotify (that XmNiconic relies on) are
+ * unreliable, since mapping changes can happen for a virtual desktop
+ * switch or MacOS style shading that became quite popular under X as
+ * well. Yes, it probably should not be this way, as it violates
+ * ICCCM, but reality is that quite a lot of window managers abuse
+ * mapping state.
+ */
+ int getWMState() {
+ if (stateChanged) {
+ stateChanged = false;
+ WindowPropertyGetter getter =
+ new WindowPropertyGetter(window, XWM.XA_WM_STATE, 0, 1, false,
+ XWM.XA_WM_STATE);
+ try {
+ int status = getter.execute();
+ if (status != XlibWrapper.Success || getter.getData() == 0) {
+ return savedState = XlibWrapper.WithdrawnState;
+ }
+
+ if (getter.getActualType() != XWM.XA_WM_STATE.getAtom() && getter.getActualFormat() != 32) {
+ return savedState = XlibWrapper.WithdrawnState;
+ }
+ savedState = (int)Native.getCard32(getter.getData());
+ } finally {
+ getter.dispose();
+ }
+ }
+ return savedState;
+ }
+
+ /**
+ * Override this methods to get notifications when top-level window state changes. The state is
+ * meant in terms of ICCCM: WithdrawnState, IconicState, NormalState
+ */
+ protected void stateChanged(long time, int oldState, int newState) {
+ }
+
+ @Override
+ public void handlePropertyNotify(XEvent xev) {
+ super.handlePropertyNotify(xev);
+ XPropertyEvent ev = xev.get_xproperty();
+ if (ev.get_atom() == XWM.XA_WM_STATE.getAtom()) {
+ // State has changed, invalidate saved value
+ stateChanged = true;
+ stateChanged(ev.get_time(), savedState, getWMState());
+ }
+ }
+
public void reshape(Rectangle bounds) {
reshape(bounds.x, bounds.y, bounds.width, bounds.height);
}
--- old/src/solaris/classes/sun/awt/X11/XWindowPeer.java 2008-12-04 19:07:27.000000000 +0300
+++ new/src/solaris/classes/sun/awt/X11/XWindowPeer.java 2008-12-04 19:07:27.000000000 +0300
@@ -52,8 +52,6 @@
protected XWindowPeer prevTransientFor, nextTransientFor;
private boolean grab = false; // Whether to do a grab during showing
- private boolean stateChanged; // Indicates whether the value on savedState is valid
- private int savedState; // Holds last known state of the top-level window
private boolean mustControlStackPosition = false; // Am override-redirect not on top
private XEventDispatcher rootPropertyEventDispatcher = null;
private boolean firstMapped = true; // Is the top-level mapped (shown) for the first time.
@@ -99,7 +97,6 @@
eventMask |= VisibilityChangeMask;
params.put(EVENT_MASK, eventMask);
- savedState = WithdrawnState;
XA_NET_WM_STATE = XAtom.get("_NET_WM_STATE");
windows.add(this);
@@ -1073,11 +1070,7 @@
public void handlePropertyNotify(XEvent xev) {
super.handlePropertyNotify(xev);
XPropertyEvent ev = xev.get_xproperty();
- if (ev.get_atom() == XWM.XA_WM_STATE.getAtom()) {
- // State has changed, invalidate saved value
- stateChanged = true;
- stateChanged(ev.get_time(), savedState, getWMState());
- } else if (ev.get_atom() == XAtom.get("_KDE_NET_WM_FRAME_STRUT").getAtom() || ev.get_atom() == XAtom.get("_NET_WM_EXTENTS").getAtom()) {
+ if (ev.get_atom() == XAtom.get("_KDE_NET_WM_FRAME_STRUT").getAtom() || ev.get_atom() == XAtom.get("_NET_WM_EXTENTS").getAtom()) {
getWMSetInsets(XAtom.get(ev.get_atom()));
}
}
@@ -1120,6 +1113,7 @@
* Override this methods to get notifications when top-level window state changes. The state is
* meant in terms of ICCCM: WithdrawnState, IconicState, NormalState
*/
+ @Override
protected void stateChanged(long time, int oldState, int newState) {
// Fix for 6401700, 6412803
// If this window is modal blocked, it is put into the transient_for
@@ -1137,38 +1131,6 @@
updateSecurityWarningVisibility();
}
-
- /*
- * XmNiconic and Map/UnmapNotify (that XmNiconic relies on) are
- * unreliable, since mapping changes can happen for a virtual desktop
- * switch or MacOS style shading that became quite popular under X as
- * well. Yes, it probably should not be this way, as it violates
- * ICCCM, but reality is that quite a lot of window managers abuse
- * mapping state.
- */
- int getWMState() {
- if (stateChanged) {
- stateChanged = false;
- WindowPropertyGetter getter =
- new WindowPropertyGetter(window, XWM.XA_WM_STATE, 0, 1, false,
- XWM.XA_WM_STATE);
- try {
- int status = getter.execute();
- if (status != XlibWrapper.Success || getter.getData() == 0) {
- return savedState = XlibWrapper.WithdrawnState;
- }
-
- if (getter.getActualType() != XWM.XA_WM_STATE.getAtom() && getter.getActualFormat() != 32) {
- return savedState = XlibWrapper.WithdrawnState;
- }
- savedState = (int)Native.getCard32(getter.getData());
- } finally {
- getter.dispose();
- }
- }
- return savedState;
- }
-
boolean isWithdrawn() {
return getWMState() == XlibWrapper.WithdrawnState;
}
|