alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (XDecoratedPeer.java)

This example Java source code file (XDecoratedPeer.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

awt, event, insets, no_embedded_check, platformlogger, point, rectangle, set_bounds, set_size, setting, windowdimensions, windowevent, xdecoratedpeer, xfocusproxywindow, xwindowpeer

The XDecoratedPeer.java Java example source code

/*
 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.awt.X11;

import java.awt.*;

import java.awt.event.ComponentEvent;
import java.awt.event.InvocationEvent;
import java.awt.event.WindowEvent;

import sun.awt.IconInfo;
import sun.util.logging.PlatformLogger;

import sun.awt.AWTAccessor;
import sun.awt.SunToolkit;

abstract class XDecoratedPeer extends XWindowPeer {
    private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XDecoratedPeer");
    private static final PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
    private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
    private static final PlatformLogger iconLog = PlatformLogger.getLogger("sun.awt.X11.icon.XDecoratedPeer");

    // Set to true when we get the first ConfigureNotify after being
    // reparented - indicates that WM has adopted the top-level.
    boolean configure_seen;
    boolean insets_corrected;

    XIconWindow iconWindow;
    WindowDimensions dimensions;
    XContentWindow content;
    Insets currentInsets;
    XFocusProxyWindow focusProxy;

    XDecoratedPeer(Window target) {
        super(target);
    }

    XDecoratedPeer(XCreateWindowParams params) {
        super(params);
    }

    public long getShell() {
        return window;
    }

    public long getContentWindow() {
        return (content == null) ? window : content.getWindow();
    }

    void preInit(XCreateWindowParams params) {
        super.preInit(params);
        winAttr.initialFocus = true;

        currentInsets = new Insets(0,0,0,0);
        applyGuessedInsets();

        Rectangle bounds = (Rectangle)params.get(BOUNDS);
        dimensions = new WindowDimensions(bounds, getRealInsets(), false);
        params.put(BOUNDS, dimensions.getClientRect());
        if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
            insLog.fine("Initial dimensions {0}", dimensions);
        }

        // Deny default processing of these events on the shell - proxy will take care of
        // them instead
        Long eventMask = (Long)params.get(EVENT_MASK);
        params.add(EVENT_MASK, Long.valueOf(eventMask.longValue() & ~(XConstants.FocusChangeMask | XConstants.KeyPressMask | XConstants.KeyReleaseMask)));
    }

    void postInit(XCreateWindowParams params) {
        // The size hints must be set BEFORE mapping the window (see 6895647)
        updateSizeHints(dimensions);

        // The super method maps the window if it's visible on the shared level
        super.postInit(params);

        // The lines that follow need to be in a postInit, so they
        // happen after the X window is created.
        initResizability();
        XWM.requestWMExtents(getWindow());

        content = XContentWindow.createContent(this);

        if (warningWindow != null) {
            warningWindow.toFront();
        }
        focusProxy = createFocusProxy();
    }

    void setIconHints(java.util.List<IconInfo> icons) {
        if (!XWM.getWM().setNetWMIcon(this, icons)) {
            if (icons.size() > 0) {
                if (iconWindow == null) {
                    iconWindow = new XIconWindow(this);
                }
                iconWindow.setIconImages(icons);
            }
        }
    }

    public void updateMinimumSize() {
        super.updateMinimumSize();
        updateMinSizeHints();
    }

    private void updateMinSizeHints() {
        if (isResizable()) {
            Dimension minimumSize = getTargetMinimumSize();
            if (minimumSize != null) {
                Insets insets = getRealInsets();
                int minWidth = minimumSize.width - insets.left - insets.right;
                int minHeight = minimumSize.height - insets.top - insets.bottom;
                if (minWidth < 0) minWidth = 0;
                if (minHeight < 0) minHeight = 0;
                setSizeHints(XUtilConstants.PMinSize | (isLocationByPlatform()?0:(XUtilConstants.PPosition | XUtilConstants.USPosition)),
                             getX(), getY(), minWidth, minHeight);
                if (isVisible()) {
                    Rectangle bounds = getShellBounds();
                    int nw = (bounds.width < minWidth) ? minWidth : bounds.width;
                    int nh = (bounds.height < minHeight) ? minHeight : bounds.height;
                    if (nw != bounds.width || nh != bounds.height) {
                        setShellSize(new Rectangle(0, 0, nw, nh));
                    }
                }
            } else {
                boolean isMinSizeSet = isMinSizeSet();
                XWM.removeSizeHints(this, XUtilConstants.PMinSize);
                /* Some WMs need remap to redecorate the window */
                if (isMinSizeSet && isShowing() && XWM.needRemap(this)) {
                    /*
                     * Do the re/mapping at the Xlib level.  Since we essentially
                     * work around a WM bug we don't want this hack to be exposed
                     * to Intrinsics (i.e. don't mess with grabs, callbacks etc).
                     */
                    xSetVisible(false);
                    XToolkit.XSync();
                    xSetVisible(true);
                }
            }
        }
    }

    XFocusProxyWindow createFocusProxy() {
        return new XFocusProxyWindow(this);
    }

    protected XAtomList getWMProtocols() {
        XAtomList protocols = super.getWMProtocols();
        protocols.add(wm_delete_window);
        protocols.add(wm_take_focus);
        return protocols;
    }

    public Graphics getGraphics() {
        AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor();
        return getGraphics(content.surfaceData,
                           compAccessor.getForeground(target),
                           compAccessor.getBackground(target),
                           compAccessor.getFont(target));
    }

    public void setTitle(String title) {
        if (log.isLoggable(PlatformLogger.Level.FINE)) {
            log.fine("Title is " + title);
        }
        winAttr.title = title;
        updateWMName();
    }

    protected String getWMName() {
        if (winAttr.title == null || winAttr.title.trim().equals("")) {
            return " ";
        } else {
            return winAttr.title;
        }
    }

    void updateWMName() {
        super.updateWMName();
        String name = getWMName();
        XToolkit.awtLock();
        try {
            if (name == null || name.trim().equals("")) {
                name = "Java";
            }
            XAtom iconNameAtom = XAtom.get(XAtom.XA_WM_ICON_NAME);
            iconNameAtom.setProperty(getWindow(), name);
            XAtom netIconNameAtom = XAtom.get("_NET_WM_ICON_NAME");
            netIconNameAtom.setPropertyUTF8(getWindow(), name);
        } finally {
            XToolkit.awtUnlock();
        }
    }

    // NOTE: This method may be called by privileged threads.
    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
    public void handleIconify() {
        postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_ICONIFIED));
    }

    // NOTE: This method may be called by privileged threads.
    //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
    public void handleDeiconify() {
        postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_DEICONIFIED));
    }

    public void handleFocusEvent(XEvent xev) {
        super.handleFocusEvent(xev);
        XFocusChangeEvent xfe = xev.get_xfocus();

        // If we somehow received focus events forward it instead to proxy
        // FIXME: Shouldn't we instead check for inferrior?
        if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
            focusLog.finer("Received focus event on shell: " + xfe);
        }
//         focusProxy.xRequestFocus();
   }

/***************************************************************************************
 *                             I N S E T S   C O D E
 **************************************************************************************/

    protected boolean isInitialReshape() {
        return false;
    }

    private static Insets difference(Insets i1, Insets i2) {
        return new Insets(i1.top-i2.top, i1.left - i2.left, i1.bottom-i2.bottom, i1.right-i2.right);
    }

    private static boolean isNull(Insets i) {
        return (i == null) || ((i.left | i.top | i.right | i.bottom) == 0);
    }

    private static Insets copy(Insets i) {
        return new Insets(i.top, i.left, i.bottom, i.right);
    }

    // insets which we get from WM (e.g from _NET_FRAME_EXTENTS)
    private Insets wm_set_insets;

    private Insets getWMSetInsets(XAtom changedAtom) {
        if (isEmbedded()) {
            return null;
        }

        if (wm_set_insets != null) {
            return wm_set_insets;
        }

        if (changedAtom == null) {
            wm_set_insets = XWM.getInsetsFromExtents(getWindow());
        } else {
            wm_set_insets = XWM.getInsetsFromProp(getWindow(), changedAtom);
        }

        if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
            insLog.finer("FRAME_EXTENTS: {0}", wm_set_insets);
        }

        if (wm_set_insets != null) {
            wm_set_insets = copy(wm_set_insets);
        }
        return wm_set_insets;
    }

    private void resetWMSetInsets() {
        wm_set_insets = null;
    }

    public void handlePropertyNotify(XEvent xev) {
        super.handlePropertyNotify(xev);

        XPropertyEvent ev = xev.get_xproperty();
        if (ev.get_atom() == XWM.XA_KDE_NET_WM_FRAME_STRUT.getAtom()
            || ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom())
        {
            getWMSetInsets(XAtom.get(ev.get_atom()));
        }
    }

    long reparent_serial = 0;

    public void handleReparentNotifyEvent(XEvent xev) {
        XReparentEvent  xe = xev.get_xreparent();
        if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
            insLog.fine(xe.toString());
        }
        reparent_serial = xe.get_serial();
        XToolkit.awtLock();
        try {
            long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());

            if (isEmbedded()) {
                setReparented(true);
                insets_corrected = true;
                return;
            }
            Component t = (Component)target;
            if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
                setReparented(true);
                insets_corrected = true;
                reshape(dimensions, SET_SIZE, false);
            } else if (xe.get_parent() == root) {
                configure_seen = false;
                insets_corrected = false;

                /*
                 * We can be repareted to root for two reasons:
                 *   . setVisible(false)
                 *   . WM exited
                 */
                if (isVisible()) { /* WM exited */
                    /* Work around 4775545 */
                    XWM.getWM().unshadeKludge(this);
                    insLog.fine("- WM exited");
                } else {
                    insLog.fine(" - reparent due to hide");
                }
            } else { /* reparented to WM frame, figure out our insets */
                setReparented(true);
                insets_corrected = false;

                // Check if we have insets provided by the WM
                Insets correctWM = getWMSetInsets(null);
                if (correctWM != null) {
                    if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
                        insLog.finer("wm-provided insets {0}", correctWM);
                    }
                    // If these insets are equal to our current insets - no actions are necessary
                    Insets dimInsets = dimensions.getInsets();
                    if (correctWM.equals(dimInsets)) {
                        insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
                        no_reparent_artifacts = true;
                        insets_corrected = true;
                        applyGuessedInsets();
                        return;
                    }
                } else {
                    correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());

                    if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
                        if (correctWM != null) {
                            insLog.finer("correctWM {0}", correctWM);
                        } else {
                            insLog.finer("correctWM insets are not available, waiting for configureNotify");
                        }
                    }
                }

                if (correctWM != null) {
                    handleCorrectInsets(correctWM);
                }
            }
        } finally {
            XToolkit.awtUnlock();
        }
    }

    protected void handleCorrectInsets(Insets correctWM) {
        XToolkit.awtLock();
        try {
            /*
             * Ok, now see if we need adjust window size because
             * initial insets were wrong (most likely they were).
             */
            Insets correction = difference(correctWM, currentInsets);
            if (insLog.isLoggable(PlatformLogger.Level.FINEST)) {
                insLog.finest("Corrention {0}", correction);
            }
            if (!isNull(correction)) {
                currentInsets = copy(correctWM);
                applyGuessedInsets();

                //Fix for 6318109: PIT: Min Size is not honored properly when a
                //smaller size is specified in setSize(), XToolkit
                //update minimum size hints
                updateMinSizeHints();
            }
            if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
                insLog.finer("Dimensions before reparent: " + dimensions);
            }

            dimensions.setInsets(getRealInsets());
            insets_corrected = true;

            if (isMaximized()) {
                return;
            }

            /*
             * If this window has been sized by a pack() we need
             * to keep the interior geometry intact.  Since pack()
             * computed width and height with wrong insets, we
             * must adjust the target dimensions appropriately.
             */
            if ((getHints().get_flags() & (XUtilConstants.USPosition | XUtilConstants.PPosition)) != 0) {
                reshape(dimensions, SET_BOUNDS, false);
            } else {
                reshape(dimensions, SET_SIZE, false);
            }
        } finally {
            XToolkit.awtUnlock();
        }
    }

    public void handleMoved(WindowDimensions dims) {
        Point loc = dims.getLocation();
        AWTAccessor.getComponentAccessor().setLocation((Component)target, loc.x, loc.y);
        postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
    }


    protected Insets guessInsets() {
        if (isEmbedded() || isTargetUndecorated()) {
            return new Insets(0, 0, 0, 0);
        } else {
            if (!isNull(currentInsets)) {
                /* insets were set on wdata by System Properties */
                return copy(currentInsets);
            } else {
                Insets res = getWMSetInsets(null);
                if (res == null) {
                    res = XWM.getWM().guessInsets(this);
                }
                return res;
            }
        }
    }

    private void applyGuessedInsets() {
        Insets guessed = guessInsets();
        currentInsets = copy(guessed);
    }

    public void revalidate() {
        XToolkit.executeOnEventHandlerThread(target, new Runnable() {
                public void run() {
                    target.invalidate();
                    target.validate();
                }
            });
    }

    Insets getRealInsets() {
        if (isNull(currentInsets)) {
            applyGuessedInsets();
        }
        return currentInsets;
    }

    public Insets getInsets() {
        Insets in = copy(getRealInsets());
        in.top += getMenuBarHeight();
        if (insLog.isLoggable(PlatformLogger.Level.FINEST)) {
            insLog.finest("Get insets returns {0}", in);
        }
        return in;
    }

    boolean gravityBug() {
        return XWM.configureGravityBuggy();
    }

    // The height of area used to display current active input method
    int getInputMethodHeight() {
        return 0;
    }

    void updateSizeHints(WindowDimensions dims) {
        Rectangle rec = dims.getClientRect();
        checkShellRect(rec);
        updateSizeHints(rec.x, rec.y, rec.width, rec.height);
    }

    void updateSizeHints() {
        updateSizeHints(dimensions);
    }

    // Coordinates are that of the target
    // Called only on Toolkit thread
    public void reshape(WindowDimensions newDimensions, int op,
                        boolean userReshape)
    {
        if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
            insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
        }
        if (userReshape) {
            // We handle only userReshape == true cases. It means that
            // if the window manager or any other part of the windowing
            // system sets inappropriate size for this window, we can
            // do nothing but accept it.
            Rectangle newBounds = newDimensions.getBounds();
            Insets insets = newDimensions.getInsets();
            // Inherit isClientSizeSet from newDimensions
            if (newDimensions.isClientSizeSet()) {
                newBounds = new Rectangle(newBounds.x, newBounds.y,
                                          newBounds.width - insets.left - insets.right,
                                          newBounds.height - insets.top - insets.bottom);
            }
            newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet());
        }
        XToolkit.awtLock();
        try {
            if (!isReparented() || !isVisible()) {
                if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
                    insLog.fine("- not reparented({0}) or not visible({1}), default reshape",
                           Boolean.valueOf(isReparented()), Boolean.valueOf(visible));
                }

                // Fix for 6323293.
                // This actually is needed to preserve compatibility with previous releases -
                // some of licensees are expecting componentMoved event on invisible one while
                // its location changes.
                Point oldLocation = getLocation();

                Point newLocation = new Point(AWTAccessor.getComponentAccessor().getX((Component)target),
                                              AWTAccessor.getComponentAccessor().getY((Component)target));

                if (!newLocation.equals(oldLocation)) {
                    handleMoved(newDimensions);
                }

                dimensions = new WindowDimensions(newDimensions);
                updateSizeHints(dimensions);
                Rectangle client = dimensions.getClientRect();
                checkShellRect(client);
                setShellBounds(client);
                if (content != null &&
                    !content.getSize().equals(newDimensions.getSize()))
                {
                    reconfigureContentWindow(newDimensions);
                }
                return;
            }

            int wm = XWM.getWMID();
            updateChildrenSizes();
            applyGuessedInsets();

            Rectangle shellRect = newDimensions.getClientRect();

            if (gravityBug()) {
                Insets in = newDimensions.getInsets();
                shellRect.translate(in.left, in.top);
            }

            if ((op & NO_EMBEDDED_CHECK) == 0 && isEmbedded()) {
                shellRect.setLocation(0, 0);
            }

            checkShellRectSize(shellRect);
            if (!isEmbedded()) {
                checkShellRectPos(shellRect);
            }

            op = op & ~NO_EMBEDDED_CHECK;

            if (op == SET_LOCATION) {
                setShellPosition(shellRect);
            } else if (isResizable()) {
                if (op == SET_BOUNDS) {
                    setShellBounds(shellRect);
                } else {
                    setShellSize(shellRect);
                }
            } else {
                XWM.setShellNotResizable(this, newDimensions, shellRect, true);
                if (op == SET_BOUNDS) {
                    setShellPosition(shellRect);
                }
            }

            reconfigureContentWindow(newDimensions);
        } finally {
            XToolkit.awtUnlock();
        }
    }

    /**
     * @param x, y, width, heith - dimensions of the window with insets
     */
    private void reshape(int x, int y, int width, int height, int operation,
                         boolean userReshape)
    {
        Rectangle newRec;
        boolean setClient = false;
        WindowDimensions dims = new WindowDimensions(dimensions);
        switch (operation & (~NO_EMBEDDED_CHECK)) {
          case SET_LOCATION:
              // Set location always sets bounds location. However, until the window is mapped we
              // should use client coordinates
              dims.setLocation(x, y);
              break;
          case SET_SIZE:
              // Set size sets bounds size. However, until the window is mapped we
              // should use client coordinates
              dims.setSize(width, height);
              break;
          case SET_CLIENT_SIZE: {
              // Sets client rect size. Width and height contain insets.
              Insets in = currentInsets;
              width -= in.left+in.right;
              height -= in.top+in.bottom;
              dims.setClientSize(width, height);
              break;
          }
          case SET_BOUNDS:
          default:
              dims.setLocation(x, y);
              dims.setSize(width, height);
              break;
        }
        if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
            insLog.fine("For the operation {0} new dimensions are {1}",
                        operationToString(operation), dims);
        }

        reshape(dims, operation, userReshape);
    }

    // This method gets overriden in XFramePeer & XDialogPeer.
    abstract boolean isTargetUndecorated();

    /**
     * @see java.awt.peer.ComponentPeer#setBounds
     */
    public void setBounds(int x, int y, int width, int height, int op) {
        // TODO: Rewrite with WindowDimensions
        reshape(x, y, width, height, op, true);
        validateSurface();
    }

    // Coordinates are that of the shell
    void reconfigureContentWindow(WindowDimensions dims) {
        if (content == null) {
            insLog.fine("WARNING: Content window is null");
            return;
        }
        content.setContentBounds(dims);
    }

    boolean no_reparent_artifacts = false;
    public void handleConfigureNotifyEvent(XEvent xev) {
        assert (SunToolkit.isAWTLockHeldByCurrentThread());
        XConfigureEvent xe = xev.get_xconfigure();
        if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
            insLog.fine("Configure notify {0}", xe);
        }

        // XXX: should really only consider synthetic events, but
        if (isReparented()) {
            configure_seen = true;
        }

        if (!isMaximized()
            && (xe.get_serial() == reparent_serial || xe.get_window() != getShell())
            && !no_reparent_artifacts)
        {
            insLog.fine("- reparent artifact, skipping");
            return;
        }
        no_reparent_artifacts = false;

        /**
         * When there is a WM we receive some CN before being visible and after.
         * We should skip all CN which are before being visible, because we assume
         * the gravity is in action while it is not yet.
         *
         * When there is no WM we receive CN only _before_ being visible.
         * We should process these CNs.
         */
        if (!isVisible() && XWM.getWMID() != XWM.NO_WM) {
            insLog.fine(" - not visible, skipping");
            return;
        }

        /*
         * Some window managers configure before we are reparented and
         * the send event flag is set! ugh... (Enlighetenment for one,
         * possibly MWM as well).  If we haven't been reparented yet
         * this is just the WM shuffling us into position.  Ignore
         * it!!!! or we wind up in a bogus location.
         */
        int runningWM = XWM.getWMID();
        if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
            insLog.fine("reparented={0}, visible={1}, WM={2}, decorations={3}",
                        isReparented(), isVisible(), runningWM, getDecorations());
        }
        if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
                &&  !XWM.isNonReparentingWM()
                && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
            insLog.fine("- visible but not reparented, skipping");
            return;
        }
        //Last chance to correct insets
        if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
            long parent = XlibUtil.getParentWindow(window);
            Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
            if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
                if (correctWM != null) {
                    insLog.finer("Configure notify - insets : " + correctWM);
                } else {
                    insLog.finer("Configure notify - insets are still not available");
                }
            }
            if (correctWM != null) {
                handleCorrectInsets(correctWM);
            } else {
                //Only one attempt to correct insets is made (to lower risk)
                //if insets are still not available we simply set the flag
                insets_corrected = true;
            }
        }

        updateChildrenSizes();

        // Bounds of the window
        Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds((Component)target);

        Point newLocation = getNewLocation(xe, currentInsets.left, currentInsets.top);

        WindowDimensions newDimensions =
                new WindowDimensions(newLocation,
                new Dimension(xe.get_width(), xe.get_height()),
                copy(currentInsets),
                true);

        if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
            insLog.finer("Insets are {0}, new dimensions {1}",
                     currentInsets, newDimensions);
        }

        checkIfOnNewScreen(newDimensions.getBounds());

        Point oldLocation = getLocation();
        dimensions = newDimensions;
        if (!newLocation.equals(oldLocation)) {
            handleMoved(newDimensions);
        }
        reconfigureContentWindow(newDimensions);
        updateChildrenSizes();

        repositionSecurityWarning();
    }

    private void checkShellRectSize(Rectangle shellRect) {
        shellRect.width = Math.max(MIN_SIZE, shellRect.width);
        shellRect.height = Math.max(MIN_SIZE, shellRect.height);
    }

    private void checkShellRectPos(Rectangle shellRect) {
        int wm = XWM.getWMID();
        if (wm == XWM.MOTIF_WM || wm == XWM.CDE_WM) {
            if (shellRect.x == 0 && shellRect.y == 0) {
                shellRect.x = shellRect.y = 1;
            }
        }
    }

    private void checkShellRect(Rectangle shellRect) {
        checkShellRectSize(shellRect);
        checkShellRectPos(shellRect);
    }

    public void setShellBounds(Rectangle rec) {
        if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
            insLog.fine("Setting shell bounds on " + this + " to " + rec);
        }
        XToolkit.awtLock();
        try {
            updateSizeHints(rec.x, rec.y, rec.width, rec.height);
            XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
            XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
        }
        finally {
            XToolkit.awtUnlock();
        }
    }
    public void setShellSize(Rectangle rec) {
        if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
            insLog.fine("Setting shell size on " + this + " to " + rec);
        }
        XToolkit.awtLock();
        try {
            updateSizeHints(rec.x, rec.y, rec.width, rec.height);
            XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
        }
        finally {
            XToolkit.awtUnlock();
        }
    }
    public void setShellPosition(Rectangle rec) {
        if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
            insLog.fine("Setting shell position on " + this + " to " + rec);
        }
        XToolkit.awtLock();
        try {
            updateSizeHints(rec.x, rec.y, rec.width, rec.height);
            XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
        }
        finally {
            XToolkit.awtUnlock();
        }
    }

    void initResizability() {
        setResizable(winAttr.initialResizability);
    }
    public void setResizable(boolean resizable) {
        int fs = winAttr.functions;
        if (!isResizable() && resizable) {
            currentInsets = new Insets(0, 0, 0, 0);
            resetWMSetInsets();
            if (!isEmbedded()) {
                setReparented(false);
            }
            winAttr.isResizable = resizable;
            if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
                fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
            } else {
                fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
            }
            winAttr.functions = fs;
            XWM.setShellResizable(this);
        } else if (isResizable() && !resizable) {
            currentInsets = new Insets(0, 0, 0, 0);
            resetWMSetInsets();
            if (!isEmbedded()) {
                setReparented(false);
            }
            winAttr.isResizable = resizable;
            if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
                fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
            } else {
                fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
            }
            winAttr.functions = fs;
            XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false);
        }
    }

    Rectangle getShellBounds() {
        return dimensions.getClientRect();
    }

    public Rectangle getBounds() {
        return dimensions.getBounds();
    }

    public Dimension getSize() {
        return dimensions.getSize();
    }

    public int getX() {
        return dimensions.getLocation().x;
    }

    public int getY() {
        return dimensions.getLocation().y;
    }

    public Point getLocation() {
        return dimensions.getLocation();
    }

    public int getAbsoluteX() {
        // NOTE: returning this peer's location which is shell location
        return dimensions.getScreenBounds().x;
    }

    public int getAbsoluteY() {
        // NOTE: returning this peer's location which is shell location
        return dimensions.getScreenBounds().y;
    }

    public int getWidth() {
        return getSize().width;
    }

    public int getHeight() {
        return getSize().height;
    }

    final public WindowDimensions getDimensions() {
        return dimensions;
    }

    public Point getLocationOnScreen() {
        XToolkit.awtLock();
        try {
            if (configure_seen) {
                return toGlobal(0,0);
            } else {
                Point location = target.getLocation();
                if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
                    insLog.fine("getLocationOnScreen {0} not reparented: {1} ",
                                this, location);
                }
                return location;
            }
        } finally {
            XToolkit.awtUnlock();
        }
    }


/***************************************************************************************
 *              END            OF             I N S E T S   C O D E
 **************************************************************************************/

    protected boolean isEventDisabled(XEvent e) {
        switch (e.get_type()) {
            // Do not generate MOVED/RESIZED events since we generate them by ourselves
          case XConstants.ConfigureNotify:
              return true;
          case XConstants.EnterNotify:
          case XConstants.LeaveNotify:
              // Disable crossing event on outer borders of Frame so
              // we receive only one set of cross notifications(first set is from content window)
              return true;
          default:
              return super.isEventDisabled(e);
        }
    }

    int getDecorations() {
        return winAttr.decorations;
    }

    int getFunctions() {
        return winAttr.functions;
    }

    public void setVisible(boolean vis) {
        if (log.isLoggable(PlatformLogger.Level.FINER)) {
            log.finer("Setting {0} to visible {1}", this, Boolean.valueOf(vis));
        }
        if (vis && !isVisible()) {
            XWM.setShellDecor(this);
            super.setVisible(vis);
            if (winAttr.isResizable) {
                //Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.
                //We need to update frame's minimum size, not to reset it
                XWM.removeSizeHints(this, XUtilConstants.PMaxSize);
                updateMinimumSize();
            }
        } else {
            super.setVisible(vis);
        }
    }

    protected void suppressWmTakeFocus(boolean doSuppress) {
        XAtomList protocols = getWMProtocols();
        if (doSuppress) {
            protocols.remove(wm_take_focus);
        } else {
            protocols.add(wm_take_focus);
        }
        wm_protocols.setAtomListProperty(this, protocols);
    }

    public void dispose() {
        if (content != null) {
            content.destroy();
        }
        focusProxy.destroy();

        if (iconWindow != null) {
            iconWindow.destroy();
        }

        super.dispose();
    }

    public void handleClientMessage(XEvent xev) {
        super.handleClientMessage(xev);
        XClientMessageEvent cl = xev.get_xclient();
        if ((wm_protocols != null) && (cl.get_message_type() == wm_protocols.getAtom())) {
            if (cl.get_data(0) == wm_delete_window.getAtom()) {
                handleQuit();
            } else if (cl.get_data(0) == wm_take_focus.getAtom()) {
                handleWmTakeFocus(cl);
            }
        }
    }

    private void handleWmTakeFocus(XClientMessageEvent cl) {
        if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
            focusLog.fine("WM_TAKE_FOCUS on {0}", this);
        }
        requestWindowFocus(cl.get_data(1), true);
    }

    /**
     * Requests focus to this decorated top-level by requesting X input focus
     * to the shell window.
     */
    protected void requestXFocus(long time, boolean timeProvided) {
        // We have proxied focus mechanism - instead of shell the focus is held
        // by "proxy" - invisible mapped window. When we want to set X input focus to
        // toplevel set it on proxy instead.
        if (focusProxy == null) {
            if (focusLog.isLoggable(PlatformLogger.Level.WARNING)) {
                focusLog.warning("Focus proxy is null for " + this);
            }
        } else {
            if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
                focusLog.fine("Requesting focus to proxy: " + focusProxy);
            }
            if (timeProvided) {
                focusProxy.xRequestFocus(time);
            } else {
                focusProxy.xRequestFocus();
            }
        }
    }

    XFocusProxyWindow getFocusProxy() {
        return focusProxy;
    }

    public void handleQuit() {
        postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_CLOSING));
    }

    final void dumpMe() {
        System.err.println(">>> Peer: " + x + ", " + y + ", " + width + ", " + height);
    }

    final void dumpTarget() {
        AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor();
        int getWidth = compAccessor.getWidth((Component)target);
        int getHeight = compAccessor.getHeight((Component)target);
        int getTargetX = compAccessor.getX((Component)target);
        int getTargetY = compAccessor.getY((Component)target);
        System.err.println(">>> Target: " + getTargetX + ", " + getTargetY + ", " + getWidth + ", " + getHeight);
    }

    final void dumpShell() {
        dumpWindow("Shell", getShell());
    }
    final void dumpContent() {
        dumpWindow("Content", getContentWindow());
    }
    final void dumpParent() {
        long parent = XlibUtil.getParentWindow(getShell());
        if (parent != 0)
        {
            dumpWindow("Parent", parent);
        }
        else
        {
            System.err.println(">>> NO PARENT");
        }
    }

    final void dumpWindow(String id, long window) {
        XWindowAttributes pattr = new XWindowAttributes();
        try {
            XToolkit.awtLock();
            try {
                int status =
                    XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
                                                     window, pattr.pData);
            }
            finally {
                XToolkit.awtUnlock();
            }
            System.err.println(">>>> " + id + ": " + pattr.get_x()
                               + ", " + pattr.get_y() + ", " + pattr.get_width()
                               + ", " + pattr.get_height());
        } finally {
            pattr.dispose();
        }
    }

    final void dumpAll() {
        dumpTarget();
        dumpMe();
        dumpParent();
        dumpShell();
        dumpContent();
    }

    boolean isMaximized() {
        return false;
    }

    @Override
    boolean isOverrideRedirect() {
        return Window.Type.POPUP.equals(getWindowType());
    }

    public boolean requestWindowFocus(long time, boolean timeProvided) {
        focusLog.fine("Request for decorated window focus");
        // If this is Frame or Dialog we can't assure focus request success - but we still can try
        // If this is Window and its owner Frame is active we can be sure request succedded.
        Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
        Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);

        if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
            focusLog.finer("Current window is: active={0}, focused={1}",
                       Boolean.valueOf(target == activeWindow),
                       Boolean.valueOf(target == focusedWindow));
        }

        XWindowPeer toFocus = this;
        while (toFocus.nextTransientFor != null) {
            toFocus = toFocus.nextTransientFor;
        }
        if (toFocus == null || !toFocus.focusAllowedFor()) {
            // This might change when WM will have property to determine focus policy.
            // Right now, because policy is unknown we can't be sure we succedded
            return false;
        }
        if (this == toFocus) {
            if (isWMStateNetHidden()) {
                focusLog.fine("The window is unmapped, so rejecting the request");
                return false;
            }
            if (target == activeWindow && target != focusedWindow) {
                // Happens when an owned window is currently focused
                focusLog.fine("Focus is on child window - transferring it back to the owner");
                handleWindowFocusInSync(-1);
                return true;
            }
            Window realNativeFocusedWindow = XWindowPeer.getNativeFocusedWindow();
            if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
                focusLog.finest("Real native focused window: " + realNativeFocusedWindow +
                            "\nKFM's focused window: " + focusedWindow);
            }

            // A workaround for Metacity. See 6522725, 6613426, 7147075.
            if (target == realNativeFocusedWindow && XWM.getWMID() == XWM.METACITY_WM) {
                if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
                    focusLog.fine("The window is already natively focused.");
                }
                return true;
            }
        }
        if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
            focusLog.fine("Requesting focus to " + (this == toFocus ? "this window" : toFocus));
        }

        if (timeProvided) {
            toFocus.requestXFocus(time);
        } else {
            toFocus.requestXFocus();
        }
        return (this == toFocus);
    }

    XWindowPeer actualFocusedWindow = null;
    void setActualFocusedWindow(XWindowPeer actualFocusedWindow) {
        synchronized(getStateLock()) {
            this.actualFocusedWindow = actualFocusedWindow;
        }
    }

    boolean requestWindowFocus(XWindowPeer actualFocusedWindow,
                               long time, boolean timeProvided)
    {
        setActualFocusedWindow(actualFocusedWindow);
        return requestWindowFocus(time, timeProvided);
    }
    public void handleWindowFocusIn(long serial) {
        if (null == actualFocusedWindow) {
            super.handleWindowFocusIn(serial);
        } else {
            /*
             * Fix for 6314575.
             * If this is a result of clicking on one of the Frame's component
             * then 'actualFocusedWindow' shouldn't be focused. A decision of focusing
             * it or not should be made after the appropriate Java mouse event (if any)
             * is handled by the component where 'actualFocusedWindow' value may be reset.
             *
             * The fix is based on the empiric fact consisting in that the component
             * receives native mouse event nearly at the same time the Frame receives
             * WM_TAKE_FOCUS (when FocusIn is generated via XSetInputFocus call) but
             * definetely before the Frame gets FocusIn event (when this method is called).
             */
            postEvent(new InvocationEvent(target, new Runnable() {
                public void run() {
                    XWindowPeer fw = null;
                    synchronized (getStateLock()) {
                        fw = actualFocusedWindow;
                        actualFocusedWindow = null;
                        if (null == fw || !fw.isVisible() || !fw.isFocusableWindow()) {
                            fw = XDecoratedPeer.this;
                        }
                    }
                    fw.handleWindowFocusIn_Dispatch();
                }
            }));
        }
    }

    public void handleWindowFocusOut(Window oppositeWindow, long serial) {
        Window actualFocusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();

        // If the actual focused window is not this decorated window then retain it.
        if (actualFocusedWindow != null && actualFocusedWindow != target) {
            Window owner = XWindowPeer.getDecoratedOwner(actualFocusedWindow);

            if (owner != null && owner == target) {
                setActualFocusedWindow((XWindowPeer) AWTAccessor.getComponentAccessor().getPeer(actualFocusedWindow));
            }
        }
        super.handleWindowFocusOut(oppositeWindow, serial);
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java XDecoratedPeer.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.