0N/A/*
5879N/A * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/Apackage sun.awt.X11;
0N/A
0N/Aimport java.awt.*;
0N/A
0N/Aimport java.awt.event.ComponentEvent;
0N/Aimport java.awt.event.FocusEvent;
0N/Aimport java.awt.event.WindowEvent;
0N/A
0N/Aimport java.awt.peer.ComponentPeer;
0N/Aimport java.awt.peer.WindowPeer;
0N/A
1966N/Aimport java.io.UnsupportedEncodingException;
1966N/A
1966N/Aimport java.security.AccessController;
1966N/Aimport java.security.PrivilegedAction;
1966N/A
0N/Aimport java.util.ArrayList;
0N/Aimport java.util.HashSet;
0N/Aimport java.util.Iterator;
0N/Aimport java.util.Set;
0N/Aimport java.util.Vector;
0N/A
1966N/Aimport java.util.concurrent.atomic.AtomicBoolean;
1966N/A
1696N/Aimport sun.util.logging.PlatformLogger;
0N/A
1045N/Aimport sun.awt.AWTAccessor;
0N/Aimport sun.awt.DisplayChangedListener;
0N/Aimport sun.awt.SunToolkit;
0N/Aimport sun.awt.X11GraphicsDevice;
0N/Aimport sun.awt.X11GraphicsEnvironment;
6323N/Aimport sun.awt.IconInfo;
0N/A
1045N/Aimport sun.java2d.pipe.Region;
1045N/A
0N/Aclass XWindowPeer extends XPanelPeer implements WindowPeer,
216N/A DisplayChangedListener {
0N/A
1696N/A private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XWindowPeer");
1696N/A private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XWindowPeer");
1696N/A private static final PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XWindowPeer");
1696N/A private static final PlatformLogger grabLog = PlatformLogger.getLogger("sun.awt.X11.grab.XWindowPeer");
1696N/A private static final PlatformLogger iconLog = PlatformLogger.getLogger("sun.awt.X11.icon.XWindowPeer");
0N/A
0N/A // should be synchronized on awtLock
0N/A private static Set<XWindowPeer> windows = new HashSet<XWindowPeer>();
0N/A
0N/A
0N/A private boolean cachedFocusableWindow;
0N/A XWarningWindow warningWindow;
0N/A
0N/A private boolean alwaysOnTop;
0N/A private boolean locationByPlatform;
0N/A
0N/A Dialog modalBlocker;
0N/A boolean delayedModalBlocking = false;
0N/A Dimension targetMinimumSize = null;
0N/A
0N/A private XWindowPeer ownerPeer;
0N/A
0N/A // used for modal blocking to keep existing z-order
0N/A protected XWindowPeer prevTransientFor, nextTransientFor;
0N/A // value of WM_TRANSIENT_FOR hint set on this window
0N/A private XWindowPeer curRealTransientFor;
0N/A
0N/A private boolean grab = false; // Whether to do a grab during showing
0N/A
0N/A private boolean isMapped = false; // Is this window mapped or not
0N/A private boolean mustControlStackPosition = false; // Am override-redirect not on top
0N/A private XEventDispatcher rootPropertyEventDispatcher = null;
0N/A
1966N/A private static final AtomicBoolean isStartupNotificationRemoved = new AtomicBoolean();
1966N/A
0N/A /*
0N/A * Focus related flags
0N/A */
0N/A private boolean isUnhiding = false; // Is the window unhiding.
0N/A private boolean isBeforeFirstMapNotify = false; // Is the window (being shown) between
0N/A // setVisible(true) & handleMapNotify().
0N/A
1971N/A /**
1971N/A * The type of the window.
1971N/A *
1971N/A * The type is supposed to be immutable while the peer object exists.
1971N/A * The value gets initialized in the preInit() method.
1971N/A */
1971N/A private Window.Type windowType = Window.Type.NORMAL;
1971N/A
1971N/A public final Window.Type getWindowType() {
1971N/A return windowType;
1971N/A }
1971N/A
0N/A // It need to be accessed from XFramePeer.
0N/A protected Vector <ToplevelStateListener> toplevelStateListeners = new Vector<ToplevelStateListener>();
0N/A XWindowPeer(XCreateWindowParams params) {
0N/A super(params.putIfNull(PARENT_WINDOW, Long.valueOf(0)));
0N/A }
0N/A
0N/A XWindowPeer(Window target) {
0N/A super(new XCreateWindowParams(new Object[] {
0N/A TARGET, target,
0N/A PARENT_WINDOW, Long.valueOf(0)}));
0N/A }
0N/A
0N/A /*
0N/A * This constant defines icon size recommended for using.
0N/A * Apparently, we should use XGetIconSizes which should
0N/A * return icon sizes would be most appreciated by the WM.
0N/A * However, XGetIconSizes always returns 0 for some reason.
0N/A * So the constant has been introduced.
0N/A */
0N/A private static final int PREFERRED_SIZE_FOR_ICON = 128;
0N/A
0N/A /*
0N/A * Sometimes XChangeProperty(_NET_WM_ICON) doesn't work if
0N/A * image buffer is too large. This constant holds maximum
0N/A * length of buffer which can be used with _NET_WM_ICON hint.
0N/A * It holds int's value.
0N/A */
0N/A private static final int MAXIMUM_BUFFER_LENGTH_NET_WM_ICON = (2<<15) - 1;
0N/A
0N/A void preInit(XCreateWindowParams params) {
562N/A target = (Component)params.get(TARGET);
1971N/A windowType = ((Window)target).getType();
0N/A params.put(REPARENTED,
0N/A Boolean.valueOf(isOverrideRedirect() || isSimpleWindow()));
0N/A super.preInit(params);
216N/A params.putIfNull(BIT_GRAVITY, Integer.valueOf(XConstants.NorthWestGravity));
0N/A
1066N/A long eventMask = 0;
1066N/A if (params.containsKey(EVENT_MASK)) {
1066N/A eventMask = ((Long)params.get(EVENT_MASK));
1066N/A }
1066N/A eventMask |= XConstants.VisibilityChangeMask;
1066N/A params.put(EVENT_MASK, eventMask);
1066N/A
0N/A XA_NET_WM_STATE = XAtom.get("_NET_WM_STATE");
0N/A
0N/A
0N/A params.put(OVERRIDE_REDIRECT, Boolean.valueOf(isOverrideRedirect()));
0N/A
1157N/A SunToolkit.awtLock();
1157N/A try {
1157N/A windows.add(this);
1157N/A } finally {
1157N/A SunToolkit.awtUnlock();
1157N/A }
1157N/A
0N/A cachedFocusableWindow = isFocusableWindow();
0N/A
0N/A Font f = target.getFont();
0N/A if (f == null) {
93N/A f = XWindow.getDefaultFont();
0N/A target.setFont(f);
0N/A // we should not call setFont because it will call a repaint
0N/A // which the peer may not be ready to do yet.
0N/A }
0N/A Color c = target.getBackground();
0N/A if (c == null) {
0N/A Color background = SystemColor.window;
0N/A target.setBackground(background);
0N/A // we should not call setBackGround because it will call a repaint
0N/A // which the peer may not be ready to do yet.
0N/A }
0N/A c = target.getForeground();
0N/A if (c == null) {
0N/A target.setForeground(SystemColor.windowText);
0N/A // we should not call setForeGround because it will call a repaint
0N/A // which the peer may not be ready to do yet.
0N/A }
0N/A
0N/A alwaysOnTop = ((Window)target).isAlwaysOnTop() && ((Window)target).isAlwaysOnTopSupported();
0N/A
0N/A GraphicsConfiguration gc = getGraphicsConfiguration();
0N/A ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
0N/A }
0N/A
0N/A protected String getWMName() {
0N/A String name = target.getName();
0N/A if (name == null || name.trim().equals("")) {
0N/A name = " ";
0N/A }
0N/A return name;
0N/A }
0N/A
4514N/A private static native String getLocalHostname();
4514N/A private static native int getJvmPID();
4514N/A
0N/A void postInit(XCreateWindowParams params) {
0N/A super.postInit(params);
0N/A
0N/A // Init WM_PROTOCOLS atom
0N/A initWMProtocols();
0N/A
4514N/A // Set _NET_WM_PID and WM_CLIENT_MACHINE using this JVM
4514N/A XAtom.get("WM_CLIENT_MACHINE").setProperty(getWindow(), getLocalHostname());
4514N/A XAtom.get("_NET_WM_PID").setCard32Property(getWindow(), getJvmPID());
4514N/A
0N/A // Set WM_TRANSIENT_FOR and group_leader
0N/A Window t_window = (Window)target;
0N/A Window owner = t_window.getOwner();
0N/A if (owner != null) {
0N/A ownerPeer = (XWindowPeer)owner.getPeer();
1696N/A if (focusLog.isLoggable(PlatformLogger.FINER)) {
0N/A focusLog.fine("Owner is " + owner);
0N/A focusLog.fine("Owner peer is " + ownerPeer);
0N/A focusLog.fine("Owner X window " + Long.toHexString(ownerPeer.getWindow()));
0N/A focusLog.fine("Owner content X window " + Long.toHexString(ownerPeer.getContentWindow()));
0N/A }
0N/A // as owner window may be an embedded window, we must get a toplevel window
0N/A // to set as TRANSIENT_FOR hint
0N/A long ownerWindow = ownerPeer.getWindow();
0N/A if (ownerWindow != 0) {
0N/A XToolkit.awtLock();
0N/A try {
0N/A // Set WM_TRANSIENT_FOR
1696N/A if (focusLog.isLoggable(PlatformLogger.FINE)) focusLog.fine("Setting transient on " + Long.toHexString(getWindow())
0N/A + " for " + Long.toHexString(ownerWindow));
0N/A setToplevelTransientFor(this, ownerPeer, false, true);
0N/A
0N/A // Set group leader
0N/A XWMHints hints = getWMHints();
216N/A hints.set_flags(hints.get_flags() | (int)XUtilConstants.WindowGroupHint);
0N/A hints.set_window_group(ownerWindow);
0N/A XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
0N/A }
0N/A finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A }
0N/A
4618N/A if (owner != null || isSimpleWindow()) {
4618N/A XToolkit.awtLock();
4618N/A try {
4618N/A XNETProtocol protocol = XWM.getWM().getNETProtocol();
4618N/A if (protocol != null && protocol.active()) {
4618N/A XAtomList net_wm_state = getNETWMState();
4618N/A net_wm_state.add(protocol.XA_NET_WM_STATE_SKIP_TASKBAR);
4618N/A setNETWMState(net_wm_state);
4618N/A }
4618N/A } finally {
4618N/A XToolkit.awtUnlock();
4618N/A }
4618N/A }
4618N/A
0N/A // Init warning window(for applets)
0N/A if (((Window)target).getWarningString() != null) {
0N/A // accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip
0N/A // and TrayIcon balloon windows without a warning window.
1976N/A if (!AWTAccessor.getWindowAccessor().isTrayIconWindow((Window)target)) {
1066N/A warningWindow = new XWarningWindow((Window)target, getWindow(), this);
0N/A }
0N/A }
0N/A
0N/A setSaveUnder(true);
0N/A
0N/A updateIconImages();
1045N/A
1045N/A updateShape();
1045N/A updateOpacity();
1045N/A // no need in updateOpaque() as it is no-op
0N/A }
0N/A
0N/A public void updateIconImages() {
0N/A Window target = (Window)this.target;
0N/A java.util.List<Image> iconImages = ((Window)target).getIconImages();
0N/A XWindowPeer ownerPeer = getOwnerPeer();
6323N/A winAttr.icons = new ArrayList<IconInfo>();
0N/A if (iconImages.size() != 0) {
0N/A //read icon images from target
0N/A winAttr.iconsInherited = false;
0N/A for (Iterator<Image> i = iconImages.iterator(); i.hasNext(); ) {
0N/A Image image = i.next();
0N/A if (image == null) {
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) {
0N/A log.finest("XWindowPeer.updateIconImages: Skipping the image passed into Java because it's null.");
0N/A }
0N/A continue;
0N/A }
6323N/A IconInfo iconInfo;
0N/A try {
6323N/A iconInfo = new IconInfo(image);
0N/A } catch (Exception e){
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) {
0N/A log.finest("XWindowPeer.updateIconImages: Perhaps the image passed into Java is broken. Skipping this icon.");
0N/A }
0N/A continue;
0N/A }
0N/A if (iconInfo.isValid()) {
0N/A winAttr.icons.add(iconInfo);
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Fix for CR#6425089
0N/A winAttr.icons = normalizeIconImages(winAttr.icons);
0N/A
0N/A if (winAttr.icons.size() == 0) {
0N/A //target.icons is empty or all icon images are broken
0N/A if (ownerPeer != null) {
0N/A //icon is inherited from parent
0N/A winAttr.iconsInherited = true;
0N/A winAttr.icons = ownerPeer.getIconInfo();
0N/A } else {
0N/A //default icon is used
0N/A winAttr.iconsInherited = false;
0N/A winAttr.icons = getDefaultIconInfo();
0N/A }
0N/A }
0N/A recursivelySetIcon(winAttr.icons);
0N/A }
0N/A
0N/A /*
0N/A * Sometimes XChangeProperty(_NET_WM_ICON) doesn't work if
0N/A * image buffer is too large. This function help us accommodate
0N/A * initial list of the icon images to certainly-acceptable.
0N/A * It does scale some of these icons to appropriate size
0N/A * if it's necessary.
0N/A */
6323N/A static java.util.List<IconInfo> normalizeIconImages(java.util.List<IconInfo> icons) {
6323N/A java.util.List<IconInfo> result = new ArrayList<IconInfo>();
0N/A int totalLength = 0;
0N/A boolean haveLargeIcon = false;
0N/A
6323N/A for (IconInfo icon : icons) {
0N/A int width = icon.getWidth();
0N/A int height = icon.getHeight();
0N/A int length = icon.getRawLength();
0N/A
0N/A if (width > PREFERRED_SIZE_FOR_ICON || height > PREFERRED_SIZE_FOR_ICON) {
0N/A if (haveLargeIcon) {
0N/A continue;
0N/A }
0N/A int scaledWidth = width;
0N/A int scaledHeight = height;
0N/A while (scaledWidth > PREFERRED_SIZE_FOR_ICON ||
0N/A scaledHeight > PREFERRED_SIZE_FOR_ICON) {
0N/A scaledWidth = scaledWidth / 2;
0N/A scaledHeight = scaledHeight / 2;
0N/A }
0N/A
0N/A icon.setScaledSize(scaledWidth, scaledHeight);
0N/A length = icon.getRawLength();
0N/A }
0N/A
0N/A if (totalLength + length <= MAXIMUM_BUFFER_LENGTH_NET_WM_ICON) {
0N/A totalLength += length;
0N/A result.add(icon);
0N/A if (width > PREFERRED_SIZE_FOR_ICON || height > PREFERRED_SIZE_FOR_ICON) {
0N/A haveLargeIcon = true;
0N/A }
0N/A }
0N/A }
0N/A
1696N/A if (iconLog.isLoggable(PlatformLogger.FINEST)) {
1696N/A iconLog.finest(">>> Length_ of buffer of icons data: " + totalLength +
1696N/A ", maximum length: " + MAXIMUM_BUFFER_LENGTH_NET_WM_ICON);
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A /*
0N/A * Dumps each icon from the list
0N/A */
6323N/A static void dumpIcons(java.util.List<IconInfo> icons) {
1696N/A if (iconLog.isLoggable(PlatformLogger.FINEST)) {
1696N/A iconLog.finest(">>> Sizes of icon images:");
6323N/A for (Iterator<IconInfo> i = icons.iterator(); i.hasNext(); ) {
1696N/A iconLog.finest(" {0}", i.next());
0N/A }
0N/A }
0N/A }
0N/A
6323N/A public void recursivelySetIcon(java.util.List<IconInfo> icons) {
0N/A dumpIcons(winAttr.icons);
0N/A setIconHints(icons);
0N/A Window target = (Window)this.target;
0N/A Window[] children = target.getOwnedWindows();
0N/A int cnt = children.length;
0N/A for (int i = 0; i < cnt; i++) {
0N/A ComponentPeer childPeer = children[i].getPeer();
0N/A if (childPeer != null && childPeer instanceof XWindowPeer) {
0N/A if (((XWindowPeer)childPeer).winAttr.iconsInherited) {
0N/A ((XWindowPeer)childPeer).winAttr.icons = icons;
0N/A ((XWindowPeer)childPeer).recursivelySetIcon(icons);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
6323N/A java.util.List<IconInfo> getIconInfo() {
0N/A return winAttr.icons;
0N/A }
6323N/A void setIconHints(java.util.List<IconInfo> icons) {
0N/A //This does nothing for XWindowPeer,
0N/A //It's overriden in XDecoratedPeer
0N/A }
0N/A
6323N/A private static ArrayList<IconInfo> defaultIconInfo;
6323N/A protected synchronized static java.util.List<IconInfo> getDefaultIconInfo() {
0N/A if (defaultIconInfo == null) {
6323N/A defaultIconInfo = new ArrayList<IconInfo>();
0N/A if (XlibWrapper.dataModel == 32) {
6323N/A defaultIconInfo.add(new IconInfo(sun.awt.AWTIcon32_java_icon16_png.java_icon16_png));
6323N/A defaultIconInfo.add(new IconInfo(sun.awt.AWTIcon32_java_icon24_png.java_icon24_png));
6323N/A defaultIconInfo.add(new IconInfo(sun.awt.AWTIcon32_java_icon32_png.java_icon32_png));
6323N/A defaultIconInfo.add(new IconInfo(sun.awt.AWTIcon32_java_icon48_png.java_icon48_png));
0N/A } else {
6323N/A defaultIconInfo.add(new IconInfo(sun.awt.AWTIcon64_java_icon16_png.java_icon16_png));
6323N/A defaultIconInfo.add(new IconInfo(sun.awt.AWTIcon64_java_icon24_png.java_icon24_png));
6323N/A defaultIconInfo.add(new IconInfo(sun.awt.AWTIcon64_java_icon32_png.java_icon32_png));
6323N/A defaultIconInfo.add(new IconInfo(sun.awt.AWTIcon64_java_icon48_png.java_icon48_png));
0N/A }
0N/A }
0N/A return defaultIconInfo;
0N/A }
0N/A
1045N/A private void updateShape() {
1045N/A // Shape shape = ((Window)target).getShape();
1045N/A Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
1045N/A if (shape != null) {
1045N/A applyShape(Region.getInstance(shape, null));
1045N/A }
1045N/A }
1045N/A
1045N/A private void updateOpacity() {
1045N/A // float opacity = ((Window)target).getOpacity();
1045N/A float opacity = AWTAccessor.getWindowAccessor().getOpacity((Window)target);
1045N/A if (opacity < 1.0f) {
1045N/A setOpacity(opacity);
1045N/A }
1045N/A }
1045N/A
0N/A public void updateMinimumSize() {
0N/A //This function only saves minimumSize value in XWindowPeer
0N/A //Setting WMSizeHints is implemented in XDecoratedPeer
0N/A targetMinimumSize = (((Component)target).isMinimumSizeSet()) ?
0N/A ((Component)target).getMinimumSize() : null;
0N/A }
0N/A
0N/A public Dimension getTargetMinimumSize() {
0N/A return (targetMinimumSize == null) ? null : new Dimension(targetMinimumSize);
0N/A }
0N/A
0N/A public XWindowPeer getOwnerPeer() {
0N/A return ownerPeer;
0N/A }
0N/A
0N/A //Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges
0N/A //the window but fails to revalidate, Sol-CDE
0N/A //This bug is regression for
0N/A //5025858: Resizing a decorated frame triggers componentResized event twice.
0N/A //Since events are not posted from Component.setBounds we need to send them here.
0N/A //Note that this function is overriden in XDecoratedPeer so event
0N/A //posting is not changing for decorated peers
0N/A public void setBounds(int x, int y, int width, int height, int op) {
0N/A XToolkit.awtLock();
0N/A try {
0N/A Rectangle oldBounds = getBounds();
106N/A
1158N/A super.setBounds(x, y, width, height, op);
106N/A
0N/A Rectangle bounds = getBounds();
0N/A
0N/A XSizeHints hints = getHints();
216N/A setSizeHints(hints.get_flags() | XUtilConstants.PPosition | XUtilConstants.PSize,
0N/A bounds.x, bounds.y, bounds.width, bounds.height);
0N/A XWM.setMotifDecor(this, false, 0, 0);
0N/A
1066N/A boolean isResized = !bounds.getSize().equals(oldBounds.getSize());
1066N/A boolean isMoved = !bounds.getLocation().equals(oldBounds.getLocation());
1066N/A if (isMoved || isResized) {
1066N/A repositionSecurityWarning();
1066N/A }
1066N/A if (isResized) {
0N/A postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_RESIZED));
0N/A }
1066N/A if (isMoved) {
0N/A postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_MOVED));
0N/A }
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
0N/A void updateFocusability() {
0N/A updateFocusableWindowState();
0N/A XToolkit.awtLock();
0N/A try {
0N/A XWMHints hints = getWMHints();
216N/A hints.set_flags(hints.get_flags() | (int)XUtilConstants.InputHint);
0N/A hints.set_input(false/*isNativelyNonFocusableWindow() ? (0):(1)*/);
0N/A XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
0N/A }
0N/A finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
0N/A public Insets getInsets() {
1066N/A return new Insets(0, 0, 0, 0);
0N/A }
0N/A
0N/A // NOTE: This method may be called by privileged threads.
0N/A // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0N/A public void handleIconify() {
0N/A postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_ICONIFIED));
0N/A }
0N/A
0N/A // NOTE: This method may be called by privileged threads.
0N/A // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0N/A public void handleDeiconify() {
0N/A postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_DEICONIFIED));
0N/A }
0N/A
0N/A // NOTE: This method may be called by privileged threads.
0N/A // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0N/A public void handleStateChange(int oldState, int newState) {
0N/A postEvent(new WindowEvent((Window)target,
0N/A WindowEvent.WINDOW_STATE_CHANGED,
0N/A oldState, newState));
0N/A }
0N/A
0N/A /**
0N/A * DEPRECATED: Replaced by getInsets().
0N/A */
0N/A public Insets insets() {
0N/A return getInsets();
0N/A }
0N/A
0N/A boolean isAutoRequestFocus() {
0N/A if (XToolkit.isToolkitThread()) {
1976N/A return AWTAccessor.getWindowAccessor().isAutoRequestFocus((Window)target);
0N/A } else {
0N/A return ((Window)target).isAutoRequestFocus();
0N/A }
0N/A }
0N/A
0N/A /*
219N/A * Retrives real native focused window and converts it into Java peer.
0N/A */
0N/A static XWindowPeer getNativeFocusedWindowPeer() {
0N/A XBaseWindow baseWindow = XToolkit.windowToXWindow(xGetInputFocus());
0N/A return (baseWindow instanceof XWindowPeer) ? (XWindowPeer)baseWindow :
0N/A (baseWindow instanceof XFocusProxyWindow) ?
0N/A ((XFocusProxyWindow)baseWindow).getOwner() : null;
0N/A }
0N/A
219N/A /*
219N/A * Retrives real native focused window and converts it into Java window.
219N/A */
219N/A static Window getNativeFocusedWindow() {
219N/A XWindowPeer peer = getNativeFocusedWindowPeer();
219N/A return peer != null ? (Window)peer.target : null;
219N/A }
219N/A
0N/A boolean isFocusableWindow() {
0N/A if (XToolkit.isToolkitThread() || SunToolkit.isAWTLockHeldByCurrentThread())
0N/A {
0N/A return cachedFocusableWindow;
0N/A } else {
0N/A return ((Window)target).isFocusableWindow();
0N/A }
0N/A }
0N/A
0N/A /* WARNING: don't call client code in this method! */
0N/A boolean isFocusedWindowModalBlocker() {
0N/A return false;
0N/A }
0N/A
0N/A long getFocusTargetWindow() {
0N/A return getContentWindow();
0N/A }
0N/A
0N/A /**
0N/A * Returns whether or not this window peer has native X window
0N/A * configured as non-focusable window. It might happen if:
0N/A * - Java window is non-focusable
0N/A * - Java window is simple Window(not Frame or Dialog)
0N/A */
0N/A boolean isNativelyNonFocusableWindow() {
0N/A if (XToolkit.isToolkitThread() || SunToolkit.isAWTLockHeldByCurrentThread())
0N/A {
0N/A return isSimpleWindow() || !cachedFocusableWindow;
0N/A } else {
0N/A return isSimpleWindow() || !(((Window)target).isFocusableWindow());
0N/A }
0N/A }
0N/A
0N/A public void handleWindowFocusIn_Dispatch() {
0N/A if (EventQueue.isDispatchThread()) {
5336N/A XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
2860N/A WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
2860N/A SunToolkit.setSystemGenerated(we);
2860N/A target.dispatchEvent(we);
0N/A }
0N/A }
0N/A
0N/A public void handleWindowFocusInSync(long serial) {
0N/A WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
5336N/A XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
0N/A sendEvent(we);
0N/A }
0N/A // NOTE: This method may be called by privileged threads.
0N/A // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0N/A public void handleWindowFocusIn(long serial) {
0N/A WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
0N/A /* wrap in Sequenced, then post*/
5336N/A XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
0N/A postEvent(wrapInSequenced((AWTEvent) we));
0N/A }
0N/A
0N/A // NOTE: This method may be called by privileged threads.
0N/A // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0N/A public void handleWindowFocusOut(Window oppositeWindow, long serial) {
0N/A WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
5336N/A XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
5336N/A XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
0N/A /* wrap in Sequenced, then post*/
0N/A postEvent(wrapInSequenced((AWTEvent) we));
0N/A }
0N/A public void handleWindowFocusOutSync(Window oppositeWindow, long serial) {
0N/A WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
5336N/A XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
5336N/A XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
0N/A sendEvent(we);
0N/A }
0N/A
0N/A/* --- DisplayChangedListener Stuff --- */
0N/A
0N/A /* Xinerama
0N/A * called to check if we've been moved onto a different screen
0N/A * Based on checkNewXineramaScreen() in awt_GraphicsEnv.c
0N/A */
0N/A public void checkIfOnNewScreen(Rectangle newBounds) {
0N/A if (!XToolkit.localEnv.runningXinerama()) {
0N/A return;
0N/A }
0N/A
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) {
0N/A log.finest("XWindowPeer: Check if we've been moved to a new screen since we're running in Xinerama mode");
0N/A }
0N/A
0N/A int area = newBounds.width * newBounds.height;
0N/A int intAmt, vertAmt, horizAmt;
0N/A int largestAmt = 0;
0N/A int curScreenNum = ((X11GraphicsDevice)getGraphicsConfiguration().getDevice()).getScreen();
0N/A int newScreenNum = 0;
0N/A GraphicsDevice gds[] = XToolkit.localEnv.getScreenDevices();
1053N/A GraphicsConfiguration newGC = null;
0N/A Rectangle screenBounds;
0N/A
0N/A for (int i = 0; i < gds.length; i++) {
0N/A screenBounds = gds[i].getDefaultConfiguration().getBounds();
0N/A if (newBounds.intersects(screenBounds)) {
0N/A horizAmt = Math.min(newBounds.x + newBounds.width,
0N/A screenBounds.x + screenBounds.width) -
0N/A Math.max(newBounds.x, screenBounds.x);
0N/A vertAmt = Math.min(newBounds.y + newBounds.height,
0N/A screenBounds.y + screenBounds.height)-
0N/A Math.max(newBounds.y, screenBounds.y);
0N/A intAmt = horizAmt * vertAmt;
0N/A if (intAmt == area) {
0N/A // Completely on this screen - done!
0N/A newScreenNum = i;
1053N/A newGC = gds[i].getDefaultConfiguration();
0N/A break;
0N/A }
0N/A if (intAmt > largestAmt) {
0N/A largestAmt = intAmt;
0N/A newScreenNum = i;
1053N/A newGC = gds[i].getDefaultConfiguration();
0N/A }
0N/A }
0N/A }
0N/A if (newScreenNum != curScreenNum) {
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) {
0N/A log.finest("XWindowPeer: Moved to a new screen");
0N/A }
1053N/A executeDisplayChangedOnEDT(newGC);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Helper method that executes the displayChanged(screen) method on
0N/A * the event dispatch thread. This method is used in the Xinerama case
0N/A * and after display mode change events.
0N/A */
1053N/A private void executeDisplayChangedOnEDT(final GraphicsConfiguration gc) {
0N/A Runnable dc = new Runnable() {
0N/A public void run() {
1053N/A AWTAccessor.getComponentAccessor().
1053N/A setGraphicsConfiguration((Component)target, gc);
0N/A }
0N/A };
0N/A SunToolkit.executeOnEventHandlerThread((Component)target, dc);
0N/A }
0N/A
0N/A /**
0N/A * From the DisplayChangedListener interface; called from
0N/A * X11GraphicsDevice when the display mode has been changed.
0N/A */
0N/A public void displayChanged() {
1053N/A executeDisplayChangedOnEDT(getGraphicsConfiguration());
0N/A }
0N/A
0N/A /**
0N/A * From the DisplayChangedListener interface; top-levels do not need
0N/A * to react to this event.
0N/A */
0N/A public void paletteChanged() {
0N/A }
0N/A
0N/A /*
0N/A * Overridden to check if we need to update our GraphicsDevice/Config
0N/A * Added for 4934052.
0N/A */
1066N/A @Override
0N/A public void handleConfigureNotifyEvent(XEvent xev) {
0N/A // TODO: We create an XConfigureEvent every time we override
0N/A // handleConfigureNotify() - too many!
0N/A XConfigureEvent xe = xev.get_xconfigure();
0N/A checkIfOnNewScreen(new Rectangle(xe.get_x(),
0N/A xe.get_y(),
0N/A xe.get_width(),
0N/A xe.get_height()));
0N/A
0N/A // Don't call super until we've handled a screen change. Otherwise
0N/A // there could be a race condition in which a ComponentListener could
0N/A // see the old screen.
0N/A super.handleConfigureNotifyEvent(xev);
1066N/A repositionSecurityWarning();
0N/A }
0N/A
0N/A final void requestXFocus(long time) {
0N/A requestXFocus(time, true);
0N/A }
0N/A
0N/A final void requestXFocus() {
0N/A requestXFocus(0, false);
0N/A }
0N/A
0N/A /**
0N/A * Requests focus to this top-level. Descendants should override to provide
0N/A * implementations based on a class of top-level.
0N/A */
0N/A protected void requestXFocus(long time, boolean timeProvided) {
0N/A // Since in XAWT focus is synthetic and all basic Windows are
0N/A // override_redirect all we can do is check whether our parent
0N/A // is active. If it is - we can freely synthesize focus transfer.
0N/A // Luckily, this logic is already implemented in requestWindowFocus.
1696N/A if (focusLog.isLoggable(PlatformLogger.FINE)) focusLog.fine("Requesting window focus");
0N/A requestWindowFocus(time, timeProvided);
0N/A }
0N/A
0N/A public final boolean focusAllowedFor() {
0N/A if (isNativelyNonFocusableWindow()) {
0N/A return false;
0N/A }
0N/A/*
0N/A Window target = (Window)this.target;
0N/A if (!target.isVisible() ||
0N/A !target.isEnabled() ||
0N/A !target.isFocusable())
0N/A {
0N/A return false;
0N/A }
0N/A*/
0N/A if (isModalBlocked()) {
0N/A return false;
0N/A }
0N/A return true;
0N/A }
0N/A
0N/A public void handleFocusEvent(XEvent xev) {
0N/A XFocusChangeEvent xfe = xev.get_xfocus();
0N/A FocusEvent fe;
1696N/A focusLog.fine("{0}", xfe);
0N/A if (isEventDisabled(xev)) {
0N/A return;
0N/A }
216N/A if (xev.get_type() == XConstants.FocusIn)
0N/A {
0N/A // If this window is non-focusable don't post any java focus event
0N/A if (focusAllowedFor()) {
216N/A if (xfe.get_mode() == XConstants.NotifyNormal // Normal notify
216N/A || xfe.get_mode() == XConstants.NotifyWhileGrabbed) // Alt-Tab notify
0N/A {
0N/A handleWindowFocusIn(xfe.get_serial());
0N/A }
0N/A }
0N/A }
0N/A else
0N/A {
216N/A if (xfe.get_mode() == XConstants.NotifyNormal // Normal notify
216N/A || xfe.get_mode() == XConstants.NotifyWhileGrabbed) // Alt-Tab notify
0N/A {
0N/A // If this window is non-focusable don't post any java focus event
0N/A if (!isNativelyNonFocusableWindow()) {
0N/A XWindowPeer oppositeXWindow = getNativeFocusedWindowPeer();
0N/A Object oppositeTarget = (oppositeXWindow!=null)? oppositeXWindow.getTarget() : null;
0N/A Window oppositeWindow = null;
0N/A if (oppositeTarget instanceof Window) {
0N/A oppositeWindow = (Window) oppositeTarget;
0N/A }
0N/A // Check if opposite window is non-focusable. In that case we don't want to
0N/A // post any event.
0N/A if (oppositeXWindow != null && oppositeXWindow.isNativelyNonFocusableWindow()) {
0N/A return;
0N/A }
0N/A if (this == oppositeXWindow) {
0N/A oppositeWindow = null;
0N/A } else if (oppositeXWindow instanceof XDecoratedPeer) {
0N/A if (((XDecoratedPeer) oppositeXWindow).actualFocusedWindow != null) {
0N/A oppositeXWindow = ((XDecoratedPeer) oppositeXWindow).actualFocusedWindow;
0N/A oppositeTarget = oppositeXWindow.getTarget();
0N/A if (oppositeTarget instanceof Window
0N/A && oppositeXWindow.isVisible()
0N/A && oppositeXWindow.isNativelyNonFocusableWindow())
0N/A {
0N/A oppositeWindow = ((Window) oppositeTarget);
0N/A }
0N/A }
0N/A }
0N/A handleWindowFocusOut(oppositeWindow, xfe.get_serial());
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A void setSaveUnder(boolean state) {}
0N/A
0N/A public void toFront() {
0N/A if (isOverrideRedirect() && mustControlStackPosition) {
0N/A mustControlStackPosition = false;
0N/A removeRootPropertyEventDispatcher();
0N/A }
0N/A if (isVisible()) {
0N/A super.toFront();
0N/A if (isFocusableWindow() && isAutoRequestFocus() &&
0N/A !isModalBlocked() && !isWithdrawn())
0N/A {
0N/A requestInitialFocus();
0N/A }
0N/A } else {
0N/A setVisible(true);
0N/A }
0N/A }
0N/A
0N/A public void toBack() {
0N/A XToolkit.awtLock();
0N/A try {
0N/A if(!isOverrideRedirect()) {
0N/A XlibWrapper.XLowerWindow(XToolkit.getDisplay(), getWindow());
0N/A }else{
0N/A lowerOverrideRedirect();
0N/A }
0N/A }
0N/A finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A private void lowerOverrideRedirect() {
0N/A //
0N/A // make new hash of toplevels of all windows from 'windows' hash.
0N/A // FIXME: do not call them "toplevel" as it is misleading.
0N/A //
0N/A HashSet toplevels = new HashSet();
0N/A long topl = 0, mytopl = 0;
0N/A
0N/A for (XWindowPeer xp : windows) {
0N/A topl = getToplevelWindow( xp.getWindow() );
0N/A if( xp.equals( this ) ) {
0N/A mytopl = topl;
0N/A }
0N/A if( topl > 0 )
0N/A toplevels.add( Long.valueOf( topl ) );
0N/A }
0N/A
0N/A //
0N/A // find in the root's tree:
0N/A // (1) my toplevel, (2) lowest java toplevel, (3) desktop
0N/A // We must enforce (3), (1), (2) order, upward;
0N/A // note that nautilus on the next restacking will do (1),(3),(2).
0N/A //
0N/A long laux, wDesktop = -1, wBottom = -1;
0N/A int iMy = -1, iDesktop = -1, iBottom = -1;
0N/A int i = 0;
0N/A XQueryTree xqt = new XQueryTree(XToolkit.getDefaultRootWindow());
0N/A try {
0N/A if( xqt.execute() > 0 ) {
0N/A int nchildren = xqt.get_nchildren();
0N/A long children = xqt.get_children();
0N/A for(i = 0; i < nchildren; i++) {
0N/A laux = Native.getWindow(children, i);
0N/A if( laux == mytopl ) {
0N/A iMy = i;
0N/A }else if( isDesktopWindow( laux ) ) {
0N/A // we need topmost desktop of them all.
0N/A iDesktop = i;
0N/A wDesktop = laux;
0N/A }else if(iBottom < 0 &&
0N/A toplevels.contains( Long.valueOf(laux) ) &&
0N/A laux != mytopl) {
0N/A iBottom = i;
0N/A wBottom = laux;
0N/A }
0N/A }
0N/A }
0N/A
0N/A if( (iMy < iBottom || iBottom < 0 )&& iDesktop < iMy)
0N/A return; // no action necessary
0N/A
0N/A long to_restack = Native.allocateLongArray(2);
0N/A Native.putLong(to_restack, 0, wBottom);
0N/A Native.putLong(to_restack, 1, mytopl);
0N/A XlibWrapper.XRestackWindows(XToolkit.getDisplay(), to_restack, 2);
0N/A XlibWrapper.unsafe.freeMemory(to_restack);
0N/A
0N/A
0N/A if( !mustControlStackPosition ) {
0N/A mustControlStackPosition = true;
0N/A // add root window property listener:
0N/A // somebody (eg nautilus desktop) may obscure us
0N/A addRootPropertyEventDispatcher();
0N/A }
0N/A } finally {
0N/A xqt.dispose();
0N/A }
0N/A }
0N/A /**
0N/A Get XID of closest to root window in a given window hierarchy.
0N/A FIXME: do not call it "toplevel" as it is misleading.
0N/A On error return 0.
0N/A */
0N/A private long getToplevelWindow( long w ) {
0N/A long wi = w, ret, root;
0N/A do {
0N/A ret = wi;
0N/A XQueryTree qt = new XQueryTree(wi);
0N/A try {
0N/A if (qt.execute() == 0) {
0N/A return 0;
0N/A }
0N/A root = qt.get_root();
0N/A wi = qt.get_parent();
0N/A } finally {
0N/A qt.dispose();
0N/A }
0N/A
0N/A } while (wi != root);
0N/A
0N/A return ret;
0N/A }
226N/A
226N/A private static boolean isDesktopWindow( long wi ) {
0N/A return XWM.getWM().isDesktopWindow( wi );
0N/A }
0N/A
0N/A private void updateAlwaysOnTop() {
1696N/A log.fine("Promoting always-on-top state {0}", Boolean.valueOf(alwaysOnTop));
0N/A XWM.getWM().setLayer(this,
0N/A alwaysOnTop ?
0N/A XLayerProtocol.LAYER_ALWAYS_ON_TOP :
0N/A XLayerProtocol.LAYER_NORMAL);
0N/A }
0N/A
5879N/A public void updateAlwaysOnTopState() {
5879N/A this.alwaysOnTop = ((Window) this.target).isAlwaysOnTop();
0N/A updateAlwaysOnTop();
0N/A }
0N/A
0N/A boolean isLocationByPlatform() {
0N/A return locationByPlatform;
0N/A }
0N/A
0N/A private void promoteDefaultPosition() {
0N/A this.locationByPlatform = ((Window)target).isLocationByPlatform();
0N/A if (locationByPlatform) {
0N/A XToolkit.awtLock();
0N/A try {
0N/A Rectangle bounds = getBounds();
0N/A XSizeHints hints = getHints();
216N/A setSizeHints(hints.get_flags() & ~(XUtilConstants.USPosition | XUtilConstants.PPosition),
0N/A bounds.x, bounds.y, bounds.width, bounds.height);
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void setVisible(boolean vis) {
0N/A if (!isVisible() && vis) {
0N/A isBeforeFirstMapNotify = true;
0N/A winAttr.initialFocus = isAutoRequestFocus();
0N/A if (!winAttr.initialFocus) {
0N/A /*
0N/A * It's easier and safer to temporary suppress WM_TAKE_FOCUS
0N/A * protocol itself than to ignore WM_TAKE_FOCUS client message.
0N/A * Because we will have to make the difference between
0N/A * the message come after showing and the message come after
0N/A * activation. Also, on Metacity, for some reason, we have _two_
0N/A * WM_TAKE_FOCUS client messages when showing a frame/dialog.
0N/A */
0N/A suppressWmTakeFocus(true);
0N/A }
0N/A }
0N/A updateFocusability();
0N/A promoteDefaultPosition();
1066N/A if (!vis && warningWindow != null) {
1066N/A warningWindow.setSecurityWarningVisible(false, false);
1066N/A }
0N/A super.setVisible(vis);
0N/A if (!vis && !isWithdrawn()) {
0N/A // ICCCM, 4.1.4. Changing Window State:
0N/A // "Iconic -> Withdrawn - The client should unmap the window and follow it
0N/A // with a synthetic UnmapNotify event as described later in this section."
0N/A // The same is true for Normal -> Withdrawn
0N/A XToolkit.awtLock();
0N/A try {
0N/A XUnmapEvent unmap = new XUnmapEvent();
0N/A unmap.set_window(window);
0N/A unmap.set_event(XToolkit.getDefaultRootWindow());
216N/A unmap.set_type((int)XConstants.UnmapNotify);
0N/A unmap.set_from_configure(false);
0N/A XlibWrapper.XSendEvent(XToolkit.getDisplay(), XToolkit.getDefaultRootWindow(),
216N/A false, XConstants.SubstructureNotifyMask | XConstants.SubstructureRedirectMask,
0N/A unmap.pData);
0N/A unmap.dispose();
0N/A }
0N/A finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A // method called somewhere in parent does not generate configure-notify
0N/A // event for override-redirect.
0N/A // Ergo, no reshape and bugs like 5085647 in case setBounds was
0N/A // called before setVisible.
0N/A if (isOverrideRedirect() && vis) {
0N/A updateChildrenSizes();
0N/A }
1066N/A repositionSecurityWarning();
0N/A }
0N/A
0N/A protected void suppressWmTakeFocus(boolean doSuppress) {
0N/A }
0N/A
0N/A final boolean isSimpleWindow() {
0N/A return !(target instanceof Frame || target instanceof Dialog);
0N/A }
0N/A boolean hasWarningWindow() {
106N/A return ((Window)target).getWarningString() != null;
0N/A }
0N/A
0N/A // The height of menu bar window
0N/A int getMenuBarHeight() {
0N/A return 0;
0N/A }
0N/A
1066N/A // Called when shell changes its size and requires children windows
1066N/A // to update their sizes appropriately
1066N/A void updateChildrenSizes() {
1066N/A }
1066N/A
1066N/A public void repositionSecurityWarning() {
1066N/A // NOTE: On KWin if the window/border snapping option is enabled,
1066N/A // the Java window may be swinging while it's being moved.
1066N/A // This doesn't make the application unusable though looks quite ugly.
1066N/A // Probobly we need to find some hint to assign to our Security
1066N/A // Warning window in order to exclude it from the snapping option.
1066N/A // We are not currently aware of existance of such a property.
0N/A if (warningWindow != null) {
1066N/A // We can't use the coordinates stored in the XBaseWindow since
1066N/A // they are zeros for decorated frames.
1976N/A AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor();
1976N/A int x = compAccessor.getX(target);
1976N/A int y = compAccessor.getY(target);
1976N/A int width = compAccessor.getWidth(target);
1976N/A int height = compAccessor.getHeight(target);
1066N/A warningWindow.reposition(x, y, width, height);
0N/A }
0N/A }
0N/A
1066N/A @Override
1066N/A protected void setMouseAbove(boolean above) {
1066N/A super.setMouseAbove(above);
1066N/A updateSecurityWarningVisibility();
1066N/A }
1066N/A
1890N/A @Override
1890N/A public void setFullScreenExclusiveModeState(boolean state) {
1890N/A super.setFullScreenExclusiveModeState(state);
1890N/A updateSecurityWarningVisibility();
1890N/A }
1890N/A
1066N/A public void updateSecurityWarningVisibility() {
1066N/A if (warningWindow == null) {
1066N/A return;
1066N/A }
1066N/A
1066N/A if (!isVisible()) {
1066N/A return; // The warning window should already be hidden.
0N/A }
1066N/A
1890N/A boolean show = false;
1890N/A
1890N/A if (!isFullScreenExclusiveMode()) {
1890N/A int state = getWMState();
1066N/A
1890N/A // getWMState() always returns 0 (Withdrawn) for simple windows. Hence
1890N/A // we ignore the state for such windows.
1890N/A if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
5336N/A if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() ==
1890N/A getTarget())
1890N/A {
1890N/A show = true;
1890N/A }
1890N/A
1890N/A if (isMouseAbove() || warningWindow.isMouseAbove())
1890N/A {
1890N/A show = true;
1890N/A }
1066N/A }
1066N/A }
1066N/A
1218N/A warningWindow.setSecurityWarningVisible(show, true);
0N/A }
0N/A
0N/A boolean isOverrideRedirect() {
1971N/A return XWM.getWMID() == XWM.OPENLOOK_WM ||
1971N/A Window.Type.POPUP.equals(getWindowType());
0N/A }
0N/A
0N/A final boolean isOLWMDecorBug() {
0N/A return XWM.getWMID() == XWM.OPENLOOK_WM &&
0N/A winAttr.nativeDecor == false;
0N/A }
0N/A
0N/A public void dispose() {
5315N/A if (isGrabbed()) {
5315N/A if (grabLog.isLoggable(PlatformLogger.FINE)) {
5315N/A grabLog.fine("Generating UngrabEvent on {0} because of the window disposal", this);
5315N/A }
5315N/A postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
5315N/A }
5315N/A
0N/A SunToolkit.awtLock();
5315N/A
0N/A try {
0N/A windows.remove(this);
0N/A } finally {
0N/A SunToolkit.awtUnlock();
0N/A }
5315N/A
0N/A if (warningWindow != null) {
0N/A warningWindow.destroy();
0N/A }
5315N/A
0N/A removeRootPropertyEventDispatcher();
0N/A mustControlStackPosition = false;
0N/A super.dispose();
0N/A
0N/A /*
0N/A * Fix for 6457980.
0N/A * When disposing an owned Window we should implicitly
0N/A * return focus to its decorated owner because it won't
0N/A * receive WM_TAKE_FOCUS.
0N/A */
0N/A if (isSimpleWindow()) {
5336N/A if (target == XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow()) {
0N/A Window owner = getDecoratedOwner((Window)target);
1976N/A ((XWindowPeer)AWTAccessor.getComponentAccessor().getPeer(owner)).requestWindowFocus();
0N/A }
0N/A }
0N/A }
5315N/A
0N/A boolean isResizable() {
0N/A return winAttr.isResizable;
0N/A }
0N/A
0N/A public void handleVisibilityEvent(XEvent xev) {
0N/A super.handleVisibilityEvent(xev);
0N/A XVisibilityEvent ve = xev.get_xvisibility();
0N/A winAttr.visibilityState = ve.get_state();
0N/A// if (ve.get_state() == XlibWrapper.VisibilityUnobscured) {
0N/A// // raiseInputMethodWindow
0N/A// }
1066N/A repositionSecurityWarning();
0N/A }
0N/A
0N/A void handleRootPropertyNotify(XEvent xev) {
0N/A XPropertyEvent ev = xev.get_xproperty();
0N/A if( mustControlStackPosition &&
0N/A ev.get_atom() == XAtom.get("_NET_CLIENT_LIST_STACKING").getAtom()){
0N/A // Restore stack order unhadled/spoiled by WM or some app (nautilus).
0N/A // As of now, don't use any generic machinery: just
0N/A // do toBack() again.
0N/A if(isOverrideRedirect()) {
0N/A toBack();
0N/A }
0N/A }
0N/A }
0N/A
1966N/A private void removeStartupNotification() {
1966N/A if (isStartupNotificationRemoved.getAndSet(true)) {
1966N/A return;
1966N/A }
1966N/A
1966N/A final String desktopStartupId = AccessController.doPrivileged(new PrivilegedAction<String>() {
1966N/A public String run() {
1966N/A return XToolkit.getEnv("DESKTOP_STARTUP_ID");
1966N/A }
1966N/A });
1966N/A if (desktopStartupId == null) {
1966N/A return;
1966N/A }
1966N/A
1966N/A final StringBuilder messageBuilder = new StringBuilder("remove: ID=");
1966N/A messageBuilder.append('"');
1966N/A for (int i = 0; i < desktopStartupId.length(); i++) {
1966N/A if (desktopStartupId.charAt(i) == '"' || desktopStartupId.charAt(i) == '\\') {
1966N/A messageBuilder.append('\\');
1966N/A }
1966N/A messageBuilder.append(desktopStartupId.charAt(i));
1966N/A }
1966N/A messageBuilder.append('"');
1966N/A messageBuilder.append('\0');
1966N/A final byte[] message;
1966N/A try {
1966N/A message = messageBuilder.toString().getBytes("UTF-8");
1966N/A } catch (UnsupportedEncodingException cannotHappen) {
1966N/A return;
1966N/A }
1966N/A
1966N/A XClientMessageEvent req = null;
1966N/A
1966N/A XToolkit.awtLock();
1966N/A try {
1966N/A final XAtom netStartupInfoBeginAtom = XAtom.get("_NET_STARTUP_INFO_BEGIN");
1966N/A final XAtom netStartupInfoAtom = XAtom.get("_NET_STARTUP_INFO");
1966N/A
1966N/A req = new XClientMessageEvent();
1966N/A req.set_type(XConstants.ClientMessage);
1966N/A req.set_window(getWindow());
1966N/A req.set_message_type(netStartupInfoBeginAtom.getAtom());
1966N/A req.set_format(8);
1966N/A
1966N/A for (int pos = 0; pos < message.length; pos += 20) {
1966N/A final int msglen = Math.min(message.length - pos, 20);
1966N/A int i = 0;
1966N/A for (; i < msglen; i++) {
1966N/A XlibWrapper.unsafe.putByte(req.get_data() + i, message[pos + i]);
1966N/A }
1966N/A for (; i < 20; i++) {
1966N/A XlibWrapper.unsafe.putByte(req.get_data() + i, (byte)0);
1966N/A }
1966N/A XlibWrapper.XSendEvent(XToolkit.getDisplay(),
1966N/A XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()),
1966N/A false,
1966N/A XConstants.PropertyChangeMask,
1966N/A req.pData);
1966N/A req.set_message_type(netStartupInfoAtom.getAtom());
1966N/A }
1966N/A } finally {
1966N/A XToolkit.awtUnlock();
1966N/A if (req != null) {
1966N/A req.dispose();
1966N/A }
1966N/A }
1966N/A }
1966N/A
0N/A public void handleMapNotifyEvent(XEvent xev) {
1966N/A removeStartupNotification();
1966N/A
0N/A // See 6480534.
0N/A isUnhiding |= isWMStateNetHidden();
0N/A
0N/A super.handleMapNotifyEvent(xev);
0N/A if (!winAttr.initialFocus) {
0N/A suppressWmTakeFocus(false); // restore the protocol.
0N/A /*
0N/A * For some reason, on Metacity, a frame/dialog being shown
0N/A * without WM_TAKE_FOCUS protocol doesn't get moved to the front.
0N/A * So, we do it evidently.
0N/A */
0N/A XToolkit.awtLock();
0N/A try {
0N/A XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow());
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A if (shouldFocusOnMapNotify()) {
0N/A focusLog.fine("Automatically request focus on window");
0N/A requestInitialFocus();
0N/A }
0N/A isUnhiding = false;
0N/A isBeforeFirstMapNotify = false;
0N/A updateAlwaysOnTop();
0N/A
0N/A synchronized (getStateLock()) {
0N/A if (!isMapped) {
0N/A isMapped = true;
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void handleUnmapNotifyEvent(XEvent xev) {
0N/A super.handleUnmapNotifyEvent(xev);
0N/A
0N/A // On Metacity UnmapNotify comes before PropertyNotify (for _NET_WM_STATE_HIDDEN).
0N/A // So we also check for the property later in MapNotify. See 6480534.
0N/A isUnhiding |= isWMStateNetHidden();
0N/A
0N/A synchronized (getStateLock()) {
0N/A if (isMapped) {
0N/A isMapped = false;
0N/A }
0N/A }
0N/A }
0N/A
0N/A private boolean shouldFocusOnMapNotify() {
0N/A boolean res = false;
0N/A
0N/A if (isBeforeFirstMapNotify) {
0N/A res = (winAttr.initialFocus || // Window.autoRequestFocus
0N/A isFocusedWindowModalBlocker());
0N/A } else {
0N/A res = isUnhiding; // Unhiding
0N/A }
0N/A res = res &&
0N/A isFocusableWindow() && // General focusability
0N/A !isModalBlocked(); // Modality
0N/A
0N/A return res;
0N/A }
0N/A
219N/A protected boolean isWMStateNetHidden() {
0N/A XNETProtocol protocol = XWM.getWM().getNETProtocol();
0N/A return (protocol != null && protocol.isWMStateNetHidden(this));
0N/A }
0N/A
0N/A protected void requestInitialFocus() {
0N/A requestXFocus();
0N/A }
0N/A
0N/A public void addToplevelStateListener(ToplevelStateListener l){
0N/A toplevelStateListeners.add(l);
0N/A }
0N/A
0N/A public void removeToplevelStateListener(ToplevelStateListener l){
0N/A toplevelStateListeners.remove(l);
0N/A }
0N/A
0N/A /**
0N/A * Override this methods to get notifications when top-level window state changes. The state is
0N/A * meant in terms of ICCCM: WithdrawnState, IconicState, NormalState
0N/A */
1066N/A @Override
0N/A protected void stateChanged(long time, int oldState, int newState) {
0N/A // Fix for 6401700, 6412803
0N/A // If this window is modal blocked, it is put into the transient_for
0N/A // chain using prevTransientFor and nextTransientFor hints. However,
0N/A // the real WM_TRANSIENT_FOR hint shouldn't be set for windows in
0N/A // different WM states (except for owner-window relationship), so
0N/A // if the window changes its state, its real WM_TRANSIENT_FOR hint
0N/A // should be updated accordingly.
0N/A updateTransientFor();
0N/A
0N/A for (ToplevelStateListener topLevelListenerTmp : toplevelStateListeners) {
0N/A topLevelListenerTmp.stateChangedICCCM(oldState, newState);
0N/A }
0N/A
1066N/A updateSecurityWarningVisibility();
0N/A }
0N/A
0N/A boolean isWithdrawn() {
216N/A return getWMState() == XUtilConstants.WithdrawnState;
0N/A }
0N/A
0N/A boolean hasDecorations(int decor) {
0N/A if (!winAttr.nativeDecor) {
0N/A return false;
0N/A }
0N/A else {
0N/A int myDecor = winAttr.decorations;
0N/A boolean hasBits = ((myDecor & decor) == decor);
0N/A if ((myDecor & XWindowAttributesData.AWT_DECOR_ALL) != 0)
0N/A return !hasBits;
0N/A else
0N/A return hasBits;
0N/A }
0N/A }
0N/A
0N/A void setReparented(boolean newValue) {
0N/A super.setReparented(newValue);
0N/A XToolkit.awtLock();
0N/A try {
0N/A if (isReparented() && delayedModalBlocking) {
1976N/A addToTransientFors((XDialogPeer) AWTAccessor.getComponentAccessor().getPeer(modalBlocker));
0N/A delayedModalBlocking = false;
0N/A }
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Returns a Vector of all Java top-level windows,
0N/A * sorted by their current Z-order
0N/A */
0N/A static Vector<XWindowPeer> collectJavaToplevels() {
0N/A Vector<XWindowPeer> javaToplevels = new Vector<XWindowPeer>();
0N/A Vector<Long> v = new Vector<Long>();
0N/A X11GraphicsEnvironment ge =
0N/A (X11GraphicsEnvironment)GraphicsEnvironment.getLocalGraphicsEnvironment();
0N/A GraphicsDevice[] gds = ge.getScreenDevices();
0N/A if (!ge.runningXinerama() && (gds.length > 1)) {
0N/A for (GraphicsDevice gd : gds) {
0N/A int screen = ((X11GraphicsDevice)gd).getScreen();
0N/A long rootWindow = XlibWrapper.RootWindow(XToolkit.getDisplay(), screen);
0N/A v.add(rootWindow);
0N/A }
0N/A } else {
0N/A v.add(XToolkit.getDefaultRootWindow());
0N/A }
0N/A final int windowsCount = windows.size();
0N/A while ((v.size() > 0) && (javaToplevels.size() < windowsCount)) {
0N/A long win = v.remove(0);
0N/A XQueryTree qt = new XQueryTree(win);
0N/A try {
0N/A if (qt.execute() != 0) {
0N/A int nchildren = qt.get_nchildren();
0N/A long children = qt.get_children();
0N/A // XQueryTree returns window children ordered by z-order
0N/A for (int i = 0; i < nchildren; i++) {
0N/A long child = Native.getWindow(children, i);
0N/A XBaseWindow childWindow = XToolkit.windowToXWindow(child);
0N/A // filter out Java non-toplevels
0N/A if ((childWindow != null) && !(childWindow instanceof XWindowPeer)) {
0N/A continue;
0N/A } else {
0N/A v.add(child);
0N/A }
0N/A if (childWindow instanceof XWindowPeer) {
0N/A XWindowPeer np = (XWindowPeer)childWindow;
0N/A javaToplevels.add(np);
0N/A // XQueryTree returns windows sorted by their z-order. However,
0N/A // if WM has not handled transient for hint for a child window,
0N/A // it may appear in javaToplevels before its owner. Move such
0N/A // children after their owners.
0N/A int k = 0;
0N/A XWindowPeer toCheck = javaToplevels.get(k);
0N/A while (toCheck != np) {
0N/A XWindowPeer toCheckOwnerPeer = toCheck.getOwnerPeer();
0N/A if (toCheckOwnerPeer == np) {
0N/A javaToplevels.remove(k);
0N/A javaToplevels.add(toCheck);
0N/A } else {
0N/A k++;
0N/A }
0N/A toCheck = javaToplevels.get(k);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A } finally {
0N/A qt.dispose();
0N/A }
0N/A }
0N/A return javaToplevels;
0N/A }
0N/A
0N/A public void setModalBlocked(Dialog d, boolean blocked) {
0N/A setModalBlocked(d, blocked, null);
0N/A }
0N/A public void setModalBlocked(Dialog d, boolean blocked,
0N/A Vector<XWindowPeer> javaToplevels)
0N/A {
0N/A XToolkit.awtLock();
0N/A try {
0N/A // State lock should always be after awtLock
0N/A synchronized(getStateLock()) {
1976N/A XDialogPeer blockerPeer = (XDialogPeer) AWTAccessor.getComponentAccessor().getPeer(d);
0N/A if (blocked) {
1696N/A log.fine("{0} is blocked by {1}", this, blockerPeer);
0N/A modalBlocker = d;
0N/A
0N/A if (isReparented() || XWM.isNonReparentingWM()) {
0N/A addToTransientFors(blockerPeer, javaToplevels);
0N/A } else {
0N/A delayedModalBlocking = true;
0N/A }
0N/A } else {
0N/A if (d != modalBlocker) {
0N/A throw new IllegalStateException("Trying to unblock window blocked by another dialog");
0N/A }
0N/A modalBlocker = null;
0N/A
0N/A if (isReparented() || XWM.isNonReparentingWM()) {
0N/A removeFromTransientFors();
0N/A } else {
0N/A delayedModalBlocking = false;
0N/A }
0N/A }
0N/A
0N/A updateTransientFor();
0N/A }
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Sets the TRANSIENT_FOR hint to the given top-level window. This
0N/A * method is used when a window is modal blocked/unblocked or
0N/A * changed its state from/to NormalState to/from other states.
0N/A * If window or transientForWindow are embedded frames, the containing
0N/A * top-level windows are used.
0N/A *
0N/A * @param window specifies the top-level window that the hint
0N/A * is to be set to
0N/A * @param transientForWindow the top-level window
0N/A * @param updateChain specifies if next/prevTransientFor fields are
0N/A * to be updated
0N/A * @param allStates if set to <code>true</code> then TRANSIENT_FOR hint
0N/A * is set regardless of the state of window and transientForWindow,
0N/A * otherwise it is set only if both are in the same state
0N/A */
0N/A static void setToplevelTransientFor(XWindowPeer window, XWindowPeer transientForWindow,
0N/A boolean updateChain, boolean allStates)
0N/A {
0N/A if ((window == null) || (transientForWindow == null)) {
0N/A return;
0N/A }
0N/A if (updateChain) {
0N/A window.prevTransientFor = transientForWindow;
0N/A transientForWindow.nextTransientFor = window;
0N/A }
0N/A if (window.curRealTransientFor == transientForWindow) {
0N/A return;
0N/A }
0N/A if (!allStates && (window.getWMState() != transientForWindow.getWMState())) {
0N/A return;
0N/A }
0N/A if (window.getScreenNumber() != transientForWindow.getScreenNumber()) {
0N/A return;
0N/A }
0N/A long bpw = window.getWindow();
0N/A while (!XlibUtil.isToplevelWindow(bpw) && !XlibUtil.isXAWTToplevelWindow(bpw)) {
0N/A bpw = XlibUtil.getParentWindow(bpw);
0N/A }
0N/A long tpw = transientForWindow.getWindow();
0N/A while (!XlibUtil.isToplevelWindow(tpw) && !XlibUtil.isXAWTToplevelWindow(tpw)) {
0N/A tpw = XlibUtil.getParentWindow(tpw);
0N/A }
0N/A XlibWrapper.XSetTransientFor(XToolkit.getDisplay(), bpw, tpw);
0N/A window.curRealTransientFor = transientForWindow;
0N/A }
0N/A
0N/A /*
0N/A * This method does nothing if this window is not blocked by any modal dialog.
0N/A * For modal blocked windows this method looks up for the nearest
0N/A * prevTransiendFor window that is in the same state (Normal/Iconified/Withdrawn)
0N/A * as this one and makes this window transient for it. The same operation is
0N/A * performed for nextTransientFor window.
0N/A * Values of prevTransientFor and nextTransientFor fields are not changed.
0N/A */
0N/A void updateTransientFor() {
0N/A int state = getWMState();
0N/A XWindowPeer p = prevTransientFor;
0N/A while ((p != null) && ((p.getWMState() != state) || (p.getScreenNumber() != getScreenNumber()))) {
0N/A p = p.prevTransientFor;
0N/A }
0N/A if (p != null) {
0N/A setToplevelTransientFor(this, p, false, false);
0N/A } else {
0N/A restoreTransientFor(this);
0N/A }
0N/A XWindowPeer n = nextTransientFor;
0N/A while ((n != null) && ((n.getWMState() != state) || (n.getScreenNumber() != getScreenNumber()))) {
0N/A n = n.nextTransientFor;
0N/A }
0N/A if (n != null) {
0N/A setToplevelTransientFor(n, this, false, false);
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Removes the TRANSIENT_FOR hint from the given top-level window.
0N/A * If window or transientForWindow are embedded frames, the containing
0N/A * top-level windows are used.
0N/A *
0N/A * @param window specifies the top-level window that the hint
0N/A * is to be removed from
0N/A */
0N/A private static void removeTransientForHint(XWindowPeer window) {
0N/A XAtom XA_WM_TRANSIENT_FOR = XAtom.get(XAtom.XA_WM_TRANSIENT_FOR);
0N/A long bpw = window.getWindow();
0N/A while (!XlibUtil.isToplevelWindow(bpw) && !XlibUtil.isXAWTToplevelWindow(bpw)) {
0N/A bpw = XlibUtil.getParentWindow(bpw);
0N/A }
0N/A XlibWrapper.XDeleteProperty(XToolkit.getDisplay(), bpw, XA_WM_TRANSIENT_FOR.getAtom());
0N/A window.curRealTransientFor = null;
0N/A }
0N/A
0N/A /*
0N/A * When a modal dialog is shown, all its blocked windows are lined up into
0N/A * a chain in such a way that each window is a transient_for window for
0N/A * the next one. That allows us to keep the modal dialog above all its
0N/A * blocked windows (even if there are some another modal dialogs between
0N/A * them).
0N/A * This method adds this top-level window to the chain of the given modal
0N/A * dialog. To keep the current relative z-order, we should use the
0N/A * XQueryTree to find the place to insert this window to. As each window
0N/A * can be blocked by only one modal dialog (such checks are performed in
0N/A * shared code), both this and blockerPeer are on the top of their chains
0N/A * (chains may be empty).
0N/A * If this window is a modal dialog and has its own chain, these chains are
0N/A * merged according to the current z-order (XQueryTree is used again).
0N/A * Below are some simple examples (z-order is from left to right, -- is
0N/A * modal blocking).
0N/A *
0N/A * Example 0:
0N/A * T (current chain of this, no windows are blocked by this)
0N/A * W1---B (current chain of blockerPeer, W2 is blocked by blockerPeer)
0N/A * Result is:
0N/A * W1-T-B (merged chain, all the windows are blocked by blockerPeer)
0N/A *
0N/A * Example 1:
0N/A * W1-T (current chain of this, W1 is blocked by this)
0N/A * W2-B (current chain of blockerPeer, W2 is blocked by blockerPeer)
0N/A * Result is:
0N/A * W1-T-W2-B (merged chain, all the windows are blocked by blockerPeer)
0N/A *
0N/A * Example 2:
0N/A * W1----T (current chain of this, W1 is blocked by this)
0N/A * W2---B (current chain of blockerPeer, W2 is blocked by blockerPeer)
0N/A * Result is:
0N/A * W1-W2-T-B (merged chain, all the windows are blocked by blockerPeer)
0N/A *
0N/A * This method should be called under the AWT lock.
0N/A *
0N/A * @see #removeFromTransientFors
0N/A * @see #setModalBlocked
0N/A */
0N/A private void addToTransientFors(XDialogPeer blockerPeer) {
0N/A addToTransientFors(blockerPeer, null);
0N/A }
0N/A
0N/A private void addToTransientFors(XDialogPeer blockerPeer, Vector<XWindowPeer> javaToplevels)
0N/A {
0N/A // blockerPeer chain iterator
0N/A XWindowPeer blockerChain = blockerPeer;
0N/A while (blockerChain.prevTransientFor != null) {
0N/A blockerChain = blockerChain.prevTransientFor;
0N/A }
0N/A // this window chain iterator
0N/A // each window can be blocked no more than once, so this window
0N/A // is on top of its chain
0N/A XWindowPeer thisChain = this;
0N/A while (thisChain.prevTransientFor != null) {
0N/A thisChain = thisChain.prevTransientFor;
0N/A }
0N/A // if there are no windows blocked by modalBlocker, simply add this window
0N/A // and its chain to blocker's chain
0N/A if (blockerChain == blockerPeer) {
0N/A setToplevelTransientFor(blockerPeer, this, true, false);
0N/A } else {
0N/A // Collect all the Java top-levels, if required
0N/A if (javaToplevels == null) {
0N/A javaToplevels = collectJavaToplevels();
0N/A }
0N/A // merged chain tail
0N/A XWindowPeer mergedChain = null;
0N/A for (XWindowPeer w : javaToplevels) {
0N/A XWindowPeer prevMergedChain = mergedChain;
0N/A if (w == thisChain) {
0N/A if (thisChain == this) {
0N/A if (prevMergedChain != null) {
0N/A setToplevelTransientFor(this, prevMergedChain, true, false);
0N/A }
0N/A setToplevelTransientFor(blockerChain, this, true, false);
0N/A break;
0N/A } else {
0N/A mergedChain = thisChain;
0N/A thisChain = thisChain.nextTransientFor;
0N/A }
0N/A } else if (w == blockerChain) {
0N/A mergedChain = blockerChain;
0N/A blockerChain = blockerChain.nextTransientFor;
0N/A } else {
0N/A continue;
0N/A }
0N/A if (prevMergedChain == null) {
0N/A mergedChain.prevTransientFor = null;
0N/A } else {
0N/A setToplevelTransientFor(mergedChain, prevMergedChain, true, false);
0N/A mergedChain.updateTransientFor();
0N/A }
0N/A if (blockerChain == blockerPeer) {
0N/A setToplevelTransientFor(thisChain, mergedChain, true, false);
0N/A setToplevelTransientFor(blockerChain, this, true, false);
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A
0N/A XToolkit.XSync();
0N/A }
0N/A
0N/A static void restoreTransientFor(XWindowPeer window) {
0N/A XWindowPeer ownerPeer = window.getOwnerPeer();
0N/A if (ownerPeer != null) {
0N/A setToplevelTransientFor(window, ownerPeer, false, true);
0N/A } else {
0N/A removeTransientForHint(window);
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * When a window is modally unblocked, it should be removed from its blocker
0N/A * chain, see {@link #addToTransientFor addToTransientFors} method for the
0N/A * chain definition.
0N/A * The problem is that we cannot simply restore window's original
0N/A * TRANSIENT_FOR hint (if any) and link prevTransientFor and
0N/A * nextTransientFor together as the whole chain could be created as a merge
0N/A * of two other chains in addToTransientFors. In that case, if this window is
0N/A * a modal dialog, it would lost all its own chain, if we simply exclude it
0N/A * from the chain.
0N/A * The correct behaviour of this method should be to split the chain, this
0N/A * window is currently in, into two chains. First chain is this window own
0N/A * chain (i. e. all the windows blocked by this one, directly or indirectly),
0N/A * if any, and the rest windows from the current chain.
0N/A *
0N/A * Example:
0N/A * Original state:
0N/A * W1-B1 (window W1 is blocked by B1)
0N/A * W2-B2 (window W2 is blocked by B2)
0N/A * B3 is shown and blocks B1 and B2:
0N/A * W1-W2-B1-B2-B3 (a single chain after B1.addToTransientFors() and B2.addToTransientFors())
0N/A * If we then unblock B1, the state should be:
0N/A * W1-B1 (window W1 is blocked by B1)
0N/A * W2-B2-B3 (window W2 is blocked by B2 and B2 is blocked by B3)
0N/A *
0N/A * This method should be called under the AWT lock.
0N/A *
0N/A * @see #addToTransientFors
0N/A * @see #setModalBlocked
0N/A */
0N/A private void removeFromTransientFors() {
0N/A // the head of the chain of this window
0N/A XWindowPeer thisChain = this;
0N/A // the head of the current chain
0N/A // nextTransientFor is always not null as this window is in the chain
0N/A XWindowPeer otherChain = nextTransientFor;
0N/A // the set of blockers in this chain: if this dialog blocks some other
0N/A // modal dialogs, their blocked windows should stay in this dialog's chain
0N/A Set<XWindowPeer> thisChainBlockers = new HashSet<XWindowPeer>();
0N/A thisChainBlockers.add(this);
0N/A // current chain iterator in the order from next to prev
0N/A XWindowPeer chainToSplit = prevTransientFor;
0N/A while (chainToSplit != null) {
1976N/A XWindowPeer blocker = (XWindowPeer) AWTAccessor.getComponentAccessor().getPeer(chainToSplit.modalBlocker);
0N/A if (thisChainBlockers.contains(blocker)) {
0N/A // add to this dialog's chain
0N/A setToplevelTransientFor(thisChain, chainToSplit, true, false);
0N/A thisChain = chainToSplit;
0N/A thisChainBlockers.add(chainToSplit);
0N/A } else {
0N/A // leave in the current chain
0N/A setToplevelTransientFor(otherChain, chainToSplit, true, false);
0N/A otherChain = chainToSplit;
0N/A }
0N/A chainToSplit = chainToSplit.prevTransientFor;
0N/A }
0N/A restoreTransientFor(thisChain);
0N/A thisChain.prevTransientFor = null;
0N/A restoreTransientFor(otherChain);
0N/A otherChain.prevTransientFor = null;
0N/A nextTransientFor = null;
0N/A
0N/A XToolkit.XSync();
0N/A }
0N/A
0N/A boolean isModalBlocked() {
0N/A return modalBlocker != null;
0N/A }
0N/A
0N/A static Window getDecoratedOwner(Window window) {
0N/A while ((null != window) && !(window instanceof Frame || window instanceof Dialog)) {
1976N/A window = (Window) AWTAccessor.getComponentAccessor().getParent(window);
0N/A }
0N/A return window;
0N/A }
0N/A
219N/A public boolean requestWindowFocus(XWindowPeer actualFocusedWindow) {
219N/A setActualFocusedWindow(actualFocusedWindow);
219N/A return requestWindowFocus();
219N/A }
219N/A
0N/A public boolean requestWindowFocus() {
0N/A return requestWindowFocus(0, false);
0N/A }
0N/A
0N/A public boolean requestWindowFocus(long time, boolean timeProvided) {
0N/A focusLog.fine("Request for window focus");
0N/A // If this is Frame or Dialog we can't assure focus request success - but we still can try
0N/A // If this is Window and its owner Frame is active we can be sure request succedded.
219N/A Window ownerWindow = XWindowPeer.getDecoratedOwner((Window)target);
5336N/A Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
219N/A Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
0N/A
219N/A if (isWMStateNetHidden()) {
219N/A focusLog.fine("The window is unmapped, so rejecting the request");
219N/A return false;
219N/A }
219N/A if (activeWindow == ownerWindow) {
0N/A focusLog.fine("Parent window is active - generating focus for this window");
0N/A handleWindowFocusInSync(-1);
0N/A return true;
0N/A }
219N/A focusLog.fine("Parent window is not active");
219N/A
1976N/A XDecoratedPeer wpeer = (XDecoratedPeer)AWTAccessor.getComponentAccessor().getPeer(ownerWindow);
219N/A if (wpeer != null && wpeer.requestWindowFocus(this, time, timeProvided)) {
219N/A focusLog.fine("Parent window accepted focus request - generating focus for this window");
219N/A return true;
0N/A }
0N/A focusLog.fine("Denied - parent window is not active and didn't accept focus request");
0N/A return false;
0N/A }
0N/A
0N/A // This method is to be overriden in XDecoratedPeer.
0N/A void setActualFocusedWindow(XWindowPeer actualFocusedWindow) {
0N/A }
0N/A
1971N/A /**
1971N/A * Applies the current window type.
1971N/A */
1971N/A private void applyWindowType() {
1971N/A XNETProtocol protocol = XWM.getWM().getNETProtocol();
1971N/A if (protocol == null) {
1971N/A return;
1971N/A }
1971N/A
1971N/A XAtom typeAtom = null;
1971N/A
1971N/A switch (getWindowType())
1971N/A {
1971N/A case NORMAL:
6113N/A typeAtom = (ownerPeer == null) ?
6113N/A protocol.XA_NET_WM_WINDOW_TYPE_NORMAL :
6113N/A protocol.XA_NET_WM_WINDOW_TYPE_DIALOG;
1971N/A break;
1971N/A case UTILITY:
1971N/A typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_UTILITY;
1971N/A break;
1971N/A case POPUP:
1971N/A typeAtom = protocol.XA_NET_WM_WINDOW_TYPE_POPUP_MENU;
1971N/A break;
1971N/A }
1971N/A
1971N/A if (typeAtom != null) {
1971N/A XAtomList wtype = new XAtomList();
1971N/A wtype.add(typeAtom);
1971N/A protocol.XA_NET_WM_WINDOW_TYPE.
1971N/A setAtomListProperty(getWindow(), wtype);
1971N/A } else {
1971N/A protocol.XA_NET_WM_WINDOW_TYPE.
1971N/A DeleteProperty(getWindow());
1971N/A }
1971N/A }
1971N/A
1971N/A @Override
0N/A public void xSetVisible(boolean visible) {
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Setting visible on " + this + " to " + visible);
0N/A XToolkit.awtLock();
0N/A try {
0N/A this.visible = visible;
0N/A if (visible) {
1971N/A applyWindowType();
0N/A XlibWrapper.XMapRaised(XToolkit.getDisplay(), getWindow());
0N/A } else {
0N/A XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());
0N/A }
0N/A XlibWrapper.XFlush(XToolkit.getDisplay());
0N/A }
0N/A finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
1888N/A // should be synchronized on awtLock
0N/A private int dropTargetCount = 0;
0N/A
1888N/A public void addDropTarget() {
1888N/A XToolkit.awtLock();
1888N/A try {
1888N/A if (dropTargetCount == 0) {
1888N/A long window = getWindow();
1888N/A if (window != 0) {
1888N/A XDropTargetRegistry.getRegistry().registerDropSite(window);
1888N/A }
0N/A }
1888N/A dropTargetCount++;
1888N/A } finally {
1888N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
1888N/A public void removeDropTarget() {
1888N/A XToolkit.awtLock();
1888N/A try {
1888N/A dropTargetCount--;
1888N/A if (dropTargetCount == 0) {
1888N/A long window = getWindow();
1888N/A if (window != 0) {
1888N/A XDropTargetRegistry.getRegistry().unregisterDropSite(window);
1888N/A }
0N/A }
1888N/A } finally {
1888N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A void addRootPropertyEventDispatcher() {
0N/A if( rootPropertyEventDispatcher == null ) {
0N/A rootPropertyEventDispatcher = new XEventDispatcher() {
0N/A public void dispatchEvent(XEvent ev) {
216N/A if( ev.get_type() == XConstants.PropertyNotify ) {
0N/A handleRootPropertyNotify( ev );
0N/A }
0N/A }
0N/A };
0N/A XlibWrapper.XSelectInput( XToolkit.getDisplay(),
0N/A XToolkit.getDefaultRootWindow(),
216N/A XConstants.PropertyChangeMask);
0N/A XToolkit.addEventDispatcher(XToolkit.getDefaultRootWindow(),
0N/A rootPropertyEventDispatcher);
0N/A }
0N/A }
0N/A void removeRootPropertyEventDispatcher() {
0N/A if( rootPropertyEventDispatcher != null ) {
0N/A XToolkit.removeEventDispatcher(XToolkit.getDefaultRootWindow(),
0N/A rootPropertyEventDispatcher);
0N/A rootPropertyEventDispatcher = null;
0N/A }
0N/A }
0N/A public void updateFocusableWindowState() {
0N/A cachedFocusableWindow = isFocusableWindow();
0N/A }
0N/A
0N/A XAtom XA_NET_WM_STATE;
0N/A XAtomList net_wm_state;
0N/A public XAtomList getNETWMState() {
0N/A if (net_wm_state == null) {
0N/A net_wm_state = XA_NET_WM_STATE.getAtomListPropertyList(this);
0N/A }
0N/A return net_wm_state;
0N/A }
0N/A
0N/A public void setNETWMState(XAtomList state) {
0N/A net_wm_state = state;
0N/A if (state != null) {
0N/A XA_NET_WM_STATE.setAtomListProperty(this, state);
0N/A }
0N/A }
0N/A
0N/A public PropMwmHints getMWMHints() {
0N/A if (mwm_hints == null) {
0N/A mwm_hints = new PropMwmHints();
216N/A if (!XWM.XA_MWM_HINTS.getAtomData(getWindow(), mwm_hints.pData, MWMConstants.PROP_MWM_HINTS_ELEMENTS)) {
0N/A mwm_hints.zero();
0N/A }
0N/A }
0N/A return mwm_hints;
0N/A }
0N/A
0N/A public void setMWMHints(PropMwmHints hints) {
0N/A mwm_hints = hints;
0N/A if (hints != null) {
216N/A XWM.XA_MWM_HINTS.setAtomData(getWindow(), mwm_hints.pData, MWMConstants.PROP_MWM_HINTS_ELEMENTS);
0N/A }
0N/A }
0N/A
1888N/A protected void updateDropTarget() {
1888N/A XToolkit.awtLock();
1888N/A try {
1888N/A if (dropTargetCount > 0) {
1888N/A long window = getWindow();
1888N/A if (window != 0) {
1888N/A XDropTargetRegistry.getRegistry().unregisterDropSite(window);
1888N/A XDropTargetRegistry.getRegistry().registerDropSite(window);
1888N/A }
0N/A }
1888N/A } finally {
1888N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
0N/A public void setGrab(boolean grab) {
0N/A this.grab = grab;
0N/A if (grab) {
0N/A pressTarget = this;
0N/A grabInput();
0N/A } else {
0N/A ungrabInput();
0N/A }
0N/A }
0N/A
0N/A public boolean isGrabbed() {
0N/A return grab && XAwtState.getGrabWindow() == this;
0N/A }
0N/A
0N/A public void handleXCrossingEvent(XEvent xev) {
0N/A XCrossingEvent xce = xev.get_xcrossing();
1696N/A if (grabLog.isLoggable(PlatformLogger.FINE)) {
1696N/A grabLog.fine("{0}, when grabbed {1}, contains {2}",
1696N/A xce, isGrabbed(), containsGlobal(xce.get_x_root(), xce.get_y_root()));
0N/A }
0N/A if (isGrabbed()) {
0N/A // When window is grabbed, all events are dispatched to
0N/A // it. Retarget them to the corresponding windows (notice
0N/A // that XBaseWindow.dispatchEvent does the opposite
0N/A // translation)
0N/A // Note that we need to retarget XCrossingEvents to content window
0N/A // since it generates MOUSE_ENTERED/MOUSE_EXITED for frame and dialog.
0N/A // (fix for 6390326)
0N/A XBaseWindow target = XToolkit.windowToXWindow(xce.get_window());
1696N/A grabLog.finer(" - Grab event target {0}", target);
0N/A if (target != null && target != this) {
0N/A target.dispatchEvent(xev);
0N/A return;
0N/A }
0N/A }
0N/A super.handleXCrossingEvent(xev);
0N/A }
0N/A
0N/A public void handleMotionNotify(XEvent xev) {
0N/A XMotionEvent xme = xev.get_xmotion();
1696N/A if (grabLog.isLoggable(PlatformLogger.FINE)) {
1696N/A grabLog.finer("{0}, when grabbed {1}, contains {2}",
1696N/A xme, isGrabbed(), containsGlobal(xme.get_x_root(), xme.get_y_root()));
0N/A }
0N/A if (isGrabbed()) {
870N/A boolean dragging = false;
1224N/A final int buttonsNumber = ((SunToolkit)(Toolkit.getDefaultToolkit())).getNumberOfButtons();
1224N/A
1224N/A for (int i = 0; i < buttonsNumber; i++){
870N/A // here is the bug in WM: extra buttons doesn't have state!=0 as they should.
870N/A if ((i != 4) && (i != 5)){
870N/A dragging = dragging || ((xme.get_state() & XConstants.buttonsMask[i]) != 0);
870N/A }
870N/A }
0N/A // When window is grabbed, all events are dispatched to
0N/A // it. Retarget them to the corresponding windows (notice
0N/A // that XBaseWindow.dispatchEvent does the opposite
0N/A // translation)
0N/A XBaseWindow target = XToolkit.windowToXWindow(xme.get_window());
0N/A if (dragging && pressTarget != target) {
0N/A // for some reasons if we grab input MotionNotify for drag is reported with target
0N/A // to underlying window, not to window on which we have initiated drag
0N/A // so we need to retarget them. Here I use simplified logic which retarget all
0N/A // such events to source of mouse press (or the grabber). It helps with fix for 6390326.
0N/A // So, I do not want to implement complicated logic for better retargeting.
0N/A target = pressTarget.isVisible() ? pressTarget : this;
0N/A xme.set_window(target.getWindow());
207N/A Point localCoord = target.toLocal(xme.get_x_root(), xme.get_y_root());
207N/A xme.set_x(localCoord.x);
207N/A xme.set_y(localCoord.y);
0N/A }
1696N/A grabLog.finer(" - Grab event target {0}", target);
0N/A if (target != null) {
0N/A if (target != getContentXWindow() && target != this) {
0N/A target.dispatchEvent(xev);
0N/A return;
0N/A }
0N/A }
0N/A
0N/A // note that we need to pass dragging events to the grabber (6390326)
0N/A // see comment above for more inforamtion.
0N/A if (!containsGlobal(xme.get_x_root(), xme.get_y_root()) && !dragging) {
0N/A // Outside of Java
0N/A return;
0N/A }
0N/A }
0N/A super.handleMotionNotify(xev);
0N/A }
0N/A
0N/A // we use it to retarget mouse drag and mouse release during grab.
0N/A private XBaseWindow pressTarget = this;
0N/A
0N/A public void handleButtonPressRelease(XEvent xev) {
0N/A XButtonEvent xbe = xev.get_xbutton();
1224N/A
1224N/A /*
1224N/A * Ignore the buttons above 20 due to the bit limit for
1224N/A * InputEvent.BUTTON_DOWN_MASK.
1224N/A * One more bit is reserved for FIRST_HIGH_BIT.
1224N/A */
1224N/A if (xbe.get_button() > SunToolkit.MAX_BUTTONS_SUPPORTED) {
1224N/A return;
1224N/A }
1696N/A if (grabLog.isLoggable(PlatformLogger.FINE)) {
1696N/A grabLog.fine("{0}, when grabbed {1}, contains {2} ({3}, {4}, {5}x{6})",
1696N/A xbe, isGrabbed(), containsGlobal(xbe.get_x_root(), xbe.get_y_root()), getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight());
0N/A }
0N/A if (isGrabbed()) {
0N/A // When window is grabbed, all events are dispatched to
0N/A // it. Retarget them to the corresponding windows (notice
0N/A // that XBaseWindow.dispatchEvent does the opposite
0N/A // translation)
0N/A XBaseWindow target = XToolkit.windowToXWindow(xbe.get_window());
0N/A try {
1696N/A grabLog.finer(" - Grab event target {0} (press target {1})", target, pressTarget);
0N/A if (xbe.get_type() == XConstants.ButtonPress
870N/A && xbe.get_button() == XConstants.buttons[0])
0N/A {
0N/A // need to keep it to retarget mouse release
0N/A pressTarget = target;
0N/A } else if (xbe.get_type() == XConstants.ButtonRelease
870N/A && xbe.get_button() == XConstants.buttons[0]
0N/A && pressTarget != target)
0N/A {
0N/A // during grab we do receive mouse release on different component (not on the source
0N/A // of mouse press). So we need to retarget it.
0N/A // see 6390326 for more information.
0N/A target = pressTarget.isVisible() ? pressTarget : this;
0N/A xbe.set_window(target.getWindow());
207N/A Point localCoord = target.toLocal(xbe.get_x_root(), xbe.get_y_root());
207N/A xbe.set_x(localCoord.x);
207N/A xbe.set_y(localCoord.y);
0N/A pressTarget = this;
0N/A }
0N/A if (target != null && target != getContentXWindow() && target != this) {
0N/A target.dispatchEvent(xev);
0N/A return;
0N/A }
0N/A } finally {
0N/A if (target != null) {
0N/A // Target is either us or our content window -
0N/A // check that event is inside. 'Us' in case of
0N/A // shell will mean that this will also filter out press on title
0N/A if ((target == this || target == getContentXWindow()) && !containsGlobal(xbe.get_x_root(), xbe.get_y_root())) {
0N/A // Outside this toplevel hierarchy
0N/A // According to the specification of UngrabEvent, post it
0N/A // when press occurs outside of the window and not on its owned windows
2127N/A if (xbe.get_type() == XConstants.ButtonPress) {
2127N/A grabLog.fine("Generating UngrabEvent on {0} because not inside of shell", this);
2127N/A postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
2127N/A return;
2127N/A }
0N/A }
0N/A // First, get the toplevel
0N/A XWindowPeer toplevel = target.getToplevelXWindow();
0N/A if (toplevel != null) {
0N/A Window w = (Window)toplevel.target;
0N/A while (w != null && toplevel != this && !(toplevel instanceof XDialogPeer)) {
1976N/A w = (Window) AWTAccessor.getComponentAccessor().getParent(w);
0N/A if (w != null) {
1976N/A toplevel = (XWindowPeer) AWTAccessor.getComponentAccessor().getPeer(w);
0N/A }
0N/A }
0N/A if (w == null || (w != this.target && w instanceof Dialog)) {
0N/A // toplevel == null - outside of
0N/A // hierarchy, toplevel is Dialog - should
0N/A // send ungrab (but shouldn't for Window)
1696N/A grabLog.fine("Generating UngrabEvent on {0} because hierarchy ended", this);
0N/A postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
0N/A }
0N/A } else {
0N/A // toplevel is null - outside of hierarchy
1696N/A grabLog.fine("Generating UngrabEvent on {0} because toplevel is null", this);
0N/A postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
0N/A return;
0N/A }
0N/A } else {
0N/A // target doesn't map to XAWT window - outside of hierarchy
1696N/A grabLog.fine("Generating UngrabEvent on because target is null {0}", this);
0N/A postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
0N/A return;
0N/A }
0N/A }
0N/A }
0N/A super.handleButtonPressRelease(xev);
0N/A }
1045N/A
1045N/A public void print(Graphics g) {
1045N/A // We assume we print the whole frame,
1045N/A // so we expect no clip was set previously
1045N/A Shape shape = AWTAccessor.getWindowAccessor().getShape((Window)target);
1045N/A if (shape != null) {
1045N/A g.setClip(shape);
1045N/A }
1045N/A super.print(g);
1045N/A }
1045N/A
1045N/A @Override
1045N/A public void setOpacity(float opacity) {
1045N/A final long maxOpacity = 0xffffffffl;
1045N/A long iOpacity = (long)(opacity * maxOpacity);
1045N/A if (iOpacity < 0) {
1045N/A iOpacity = 0;
1045N/A }
1045N/A if (iOpacity > maxOpacity) {
1045N/A iOpacity = maxOpacity;
1045N/A }
1045N/A
1045N/A XAtom netWmWindowOpacityAtom = XAtom.get("_NET_WM_WINDOW_OPACITY");
1045N/A
1045N/A if (iOpacity == maxOpacity) {
1045N/A netWmWindowOpacityAtom.DeleteProperty(getWindow());
1045N/A } else {
1045N/A netWmWindowOpacityAtom.setCard32Property(getWindow(), iOpacity);
1045N/A }
1045N/A }
1045N/A
1045N/A @Override
1045N/A public void setOpaque(boolean isOpaque) {
1045N/A // no-op
1045N/A }
1045N/A
1045N/A @Override
1222N/A public void updateWindow() {
1045N/A // no-op
1045N/A }
0N/A}