src/solaris/classes/sun/awt/X11/XDecoratedPeer.java

Print this page


   1 /*
   2  * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 package sun.awt.X11;
  26 
  27 import java.awt.*;
  28 
  29 import java.awt.event.ComponentEvent;
  30 import java.awt.event.InvocationEvent;
  31 import java.awt.event.WindowEvent;
  32 
  33 import java.util.logging.Level;
  34 import java.util.logging.Logger;
  35 

  36 import sun.awt.ComponentAccessor;
  37 import sun.awt.SunToolkit;
  38 
  39 abstract class XDecoratedPeer extends XWindowPeer {
  40     private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer");
  41     private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
  42     private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
  43     private static final Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XDecoratedPeer");
  44 
  45     // Set to true when we get the first ConfigureNotify after being
  46     // reparented - indicates that WM has adopted the top-level.
  47     boolean configure_seen;
  48     boolean insets_corrected;
  49 
  50     XIconWindow iconWindow;
  51     WindowDimensions dimensions;










  52     XContentWindow content;
  53     Insets currentInsets;
  54     XFocusProxyWindow focusProxy;
  55 
  56     XDecoratedPeer(Window target) {
  57         super(target);
  58     }
  59 
  60     XDecoratedPeer(XCreateWindowParams params) {
  61         super(params);
  62     }
  63 
  64     public long getShell() {
  65         return window;
  66     }
  67 
  68     public long getContentWindow() {
  69         return (content == null) ? window : content.getWindow();
  70     }
  71 
  72     void preInit(XCreateWindowParams params) {
  73         super.preInit(params);
  74         winAttr.initialFocus = true;
  75 
  76         currentInsets = new Insets(0,0,0,0);
  77         applyGuessedInsets();
  78 
  79         Rectangle bounds = (Rectangle)params.get(BOUNDS);
  80         dimensions = new WindowDimensions(bounds, getRealInsets(), false);
  81         params.put(BOUNDS, dimensions.getClientRect());
  82         insLog.log(Level.FINE, "Initial dimensions {0}", new Object[] { dimensions });
  83 
  84         // Deny default processing of these events on the shell - proxy will take care of
  85         // them instead
  86         Long eventMask = (Long)params.get(EVENT_MASK);
  87         params.add(EVENT_MASK, Long.valueOf(eventMask.longValue() & ~(XConstants.FocusChangeMask | XConstants.KeyPressMask | XConstants.KeyReleaseMask)));
  88     }
  89 
  90     void postInit(XCreateWindowParams params) {
  91         super.postInit(params);
  92         // The lines that follow need to be in a postInit, so they
  93         // happen after the X window is created.
  94         initResizability();
  95         updateSizeHints(dimensions);
  96         XWM.requestWMExtents(getWindow());
  97 
  98         content = XContentWindow.createContent(this);
  99 
 100         if (warningWindow != null) {
 101             warningWindow.toFront();
 102         }
 103         focusProxy = createFocusProxy();
 104     }
 105 
 106     void setIconHints(java.util.List<XIconInfo> icons) {
 107         if (!XWM.getWM().setNetWMIcon(this, icons)) {
 108             if (icons.size() > 0) {
 109                 if (iconWindow == null) {
 110                     iconWindow = new XIconWindow(this);
 111                 }
 112                 iconWindow.setIconImages(icons);
 113             }
 114         }
 115     }
 116 
 117     public void updateMinimumSize() {
 118         super.updateMinimumSize();
 119         updateMinSizeHints();
 120     }
 121 
 122     private void updateMinSizeHints() {
 123         if (isResizable()) {
 124             Dimension minimumSize = getTargetMinimumSize();
 125             if (minimumSize != null) {
 126                 Insets insets = getRealInsets();
 127                 int minWidth = minimumSize.width - insets.left - insets.right;
 128                 int minHeight = minimumSize.height - insets.top - insets.bottom;
 129                 if (minWidth < 0) minWidth = 0;
 130                 if (minHeight < 0) minHeight = 0;
 131                 setSizeHints(XUtilConstants.PMinSize | (isLocationByPlatform()?0:(XUtilConstants.PPosition | XUtilConstants.USPosition)),
 132                              getX(), getY(), minWidth, minHeight);
 133                 if (isVisible()) {
 134                     Rectangle bounds = getShellBounds();
 135                     int nw = (bounds.width < minWidth) ? minWidth : bounds.width;
 136                     int nh = (bounds.height < minHeight) ? minHeight : bounds.height;
 137                     if (nw != bounds.width || nh != bounds.height) {
 138                         setShellSize(new Rectangle(0, 0, nw, nh));
 139                     }
 140                 }
 141             } else {
 142                 boolean isMinSizeSet = isMinSizeSet();
 143                 XWM.removeSizeHints(this, XUtilConstants.PMinSize);
 144                 /* Some WMs need remap to redecorate the window */
 145                 if (isMinSizeSet && isShowing() && XWM.needRemap(this)) {
 146                     /*


 214     // NOTE: This method may be called by privileged threads.
 215     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
 216     public void handleDeiconify() {
 217         postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_DEICONIFIED));
 218     }
 219 
 220     public void handleFocusEvent(XEvent xev) {
 221         super.handleFocusEvent(xev);
 222         XFocusChangeEvent xfe = xev.get_xfocus();
 223 
 224         // If we somehow received focus events forward it instead to proxy
 225         // FIXME: Shouldn't we instead check for inferrior?
 226         focusLog.finer("Received focus event on shell: " + xfe);
 227 //         focusProxy.xRequestFocus();
 228    }
 229 
 230 /***************************************************************************************
 231  *                             I N S E T S   C O D E
 232  **************************************************************************************/
 233 
 234     protected boolean isInitialReshape() {
 235         return false;
 236     }
 237 
 238     private static Insets difference(Insets i1, Insets i2) {
 239         return new Insets(i1.top-i2.top, i1.left - i2.left, i1.bottom-i2.bottom, i1.right-i2.right);
 240     }










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






 244     }
 245 
 246     private static Insets copy(Insets i) {
 247         return new Insets(i.top, i.left, i.bottom, i.right);
 248     }
 249 
 250     // insets which we get from WM (e.g from _NET_FRAME_EXTENTS)
 251     private Insets wm_set_insets;
 252 
 253     private Insets getWMSetInsets(XAtom changedAtom) {
 254         if (isEmbedded()) {
 255             return null;
 256         }
 257 
 258         if (wm_set_insets != null) {
 259             return wm_set_insets;


 260         }
 261 
 262         if (changedAtom == null) {
 263             wm_set_insets = XWM.getInsetsFromExtents(getWindow());
 264         } else {
 265             wm_set_insets = XWM.getInsetsFromProp(getWindow(), changedAtom);
 266         }
 267 
 268         insLog.log(Level.FINER, "FRAME_EXTENTS: {0}", new Object[]{wm_set_insets});





 269 
 270         if (wm_set_insets != null) {
 271             wm_set_insets = copy(wm_set_insets);





 272         }
 273         return wm_set_insets;
 274     }
 275 
 276     private void resetWMSetInsets() {
 277         wm_set_insets = null;




 278     }
 279 
 280     public void handlePropertyNotify(XEvent xev) {
 281         super.handlePropertyNotify(xev);
 282 
 283         XPropertyEvent ev = xev.get_xproperty();
 284         if (ev.get_atom() == XWM.XA_KDE_NET_WM_FRAME_STRUT.getAtom()
 285             || ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom())
 286         {
 287             getWMSetInsets(XAtom.get(ev.get_atom()));

 288         }










 289     }
 290 
 291     long reparent_serial = 0;
 292 
 293     public void handleReparentNotifyEvent(XEvent xev) {
 294         XReparentEvent  xe = xev.get_xreparent();
 295         if (insLog.isLoggable(Level.FINE)) insLog.fine(xe.toString());
 296         reparent_serial = xe.get_serial();
 297         XToolkit.awtLock();
 298         try {
 299             long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
 300 
 301             if (isEmbedded()) {
 302                 setReparented(true);
 303                 insets_corrected = true;
 304                 return;
 305             }
 306             Component t = (Component)target;
 307             if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
 308                 setReparented(true);
 309                 insets_corrected = true;
 310                 reshape(dimensions, SET_SIZE, false);
 311             } else if (xe.get_parent() == root) {
 312                 configure_seen = false;
 313                 insets_corrected = false;
 314 
 315                 /*
 316                  * We can be repareted to root for two reasons:
 317                  *   . setVisible(false)
 318                  *   . WM exited





 319                  */
 320                 if (isVisible()) { /* WM exited */
 321                     /* Work around 4775545 */
 322                     XWM.getWM().unshadeKludge(this);
 323                     insLog.fine("- WM exited");
 324                 } else {
 325                     insLog.fine(" - reparent due to hide");
 326                 }
 327             } else { /* reparented to WM frame, figure out our insets */
 328                 setReparented(true);
 329                 insets_corrected = false;
 330 
 331                 // Check if we have insets provided by the WM
 332                 Insets correctWM = getWMSetInsets(null);
 333                 if (correctWM != null) {
 334                     insLog.log(Level.FINER, "wm-provided insets {0}", new Object[]{correctWM});
 335                     // If these insets are equal to our current insets - no actions are necessary
 336                     Insets dimInsets = dimensions.getInsets();
 337                     if (correctWM.equals(dimInsets)) {
 338                         insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
 339                         no_reparent_artifacts = true;
 340                         insets_corrected = true;
 341                         applyGuessedInsets();
 342                         return;
 343                     }
 344                 } else {
 345                     correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
 346 
 347                     if (correctWM != null) {
 348                         insLog.log(Level.FINER, "correctWM {0}", new Object[] {correctWM});
 349                     } else {
 350                         insLog.log(Level.FINER, "correctWM insets are not available, waiting for configureNotify");



 351                     }









 352                 }
 353 
 354                 if (correctWM != null) {
 355                     handleCorrectInsets(correctWM);


 356                 }
























 357             }
 358         } finally {
 359             XToolkit.awtUnlock();
 360         }
 361     }
 362 
 363     protected void handleCorrectInsets(Insets correctWM) {
 364         XToolkit.awtLock();
 365         try {
 366             /*
 367              * Ok, now see if we need adjust window size because
 368              * initial insets were wrong (most likely they were).
 369              */
 370             Insets correction = difference(correctWM, currentInsets);
 371             insLog.log(Level.FINEST, "Corrention {0}", new Object[] {correction});
 372             if (!isNull(correction)) {
 373                 currentInsets = copy(correctWM);
 374                 applyGuessedInsets();
 375 
 376                 //Fix for 6318109: PIT: Min Size is not honored properly when a
 377                 //smaller size is specified in setSize(), XToolkit
 378                 //update minimum size hints
 379                 updateMinSizeHints();
 380             }
 381             if (insLog.isLoggable(Level.FINER)) insLog.finer("Dimensions before reparent: " + dimensions);
 382 
 383             dimensions.setInsets(getRealInsets());
 384             insets_corrected = true;



 385 
 386             if (isMaximized()) {
 387                 return;

 388             }
 389 
 390             /*
 391              * If this window has been sized by a pack() we need
 392              * to keep the interior geometry intact.  Since pack()
 393              * computed width and height with wrong insets, we
 394              * must adjust the target dimensions appropriately.
 395              */
 396             if ((getHints().get_flags() & (XUtilConstants.USPosition | XUtilConstants.PPosition)) != 0) {
 397                 reshape(dimensions, SET_BOUNDS, false);
 398             } else {
 399                 reshape(dimensions, SET_SIZE, false);



 400             }
 401         } finally {
 402             XToolkit.awtUnlock();
 403         }
 404     }
 405 
 406     public void handleMoved(WindowDimensions dims) {
 407         Point loc = dims.getLocation();
 408         ComponentAccessor.setX((Component)target, loc.x);
 409         ComponentAccessor.setY((Component)target, loc.y);
 410         postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));









 411     }
 412 



 413 
 414     protected Insets guessInsets() {
 415         if (isEmbedded() || isTargetUndecorated()) {
 416             return new Insets(0, 0, 0, 0);
 417         } else {
 418             if (!isNull(currentInsets)) {
 419                 /* insets were set on wdata by System Properties */
 420                 return copy(currentInsets);
 421             } else {
 422                 Insets res = getWMSetInsets(null);
 423                 if (res == null) {
 424                     res = XWM.getWM().guessInsets(this);
 425                 }
 426                 return res;









 427             }
 428         }



 429     }
 430 
 431     private void applyGuessedInsets() {
 432         Insets guessed = guessInsets();
 433         currentInsets = copy(guessed);

 434     }
 435 

 436     public void revalidate() {
 437         XToolkit.executeOnEventHandlerThread(target, new Runnable() {
 438                 public void run() {
 439                     target.invalidate();
 440                     target.validate();
 441                 }
 442             });
 443     }
 444 
 445     Insets getRealInsets() {
 446         if (isNull(currentInsets)) {
 447             applyGuessedInsets();
 448         }
 449         return currentInsets;
 450     }
 451 
 452     public Insets getInsets() {
 453         Insets in = copy(getRealInsets());
 454         in.top += getMenuBarHeight();
 455         if (insLog.isLoggable(Level.FINEST)) {
 456             insLog.log(Level.FINEST, "Get insets returns {0}", new Object[] {in});
 457         }
 458         return in;
 459     }
 460 
 461     boolean gravityBug() {
 462         return XWM.configureGravityBuggy();
 463     }
 464 
 465     // The height of area used to display current active input method
 466     int getInputMethodHeight() {
 467         return 0;
 468     }
 469 
 470     void updateSizeHints(WindowDimensions dims) {
 471         Rectangle rec = dims.getClientRect();
 472         checkShellRect(rec);
 473         updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 474     }
 475 
 476     void updateSizeHints() {
 477         updateSizeHints(dimensions);
 478     }
 479 
 480     // Coordinates are that of the target
 481     // Called only on Toolkit thread
 482     public void reshape(WindowDimensions newDimensions, int op,
 483                         boolean userReshape)
 484     {
 485         if (insLog.isLoggable(Level.FINE)) {
 486             insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
 487         }
 488         if (userReshape) {
 489             // We handle only userReshape == true cases. It means that
 490             // if the window manager or any other part of the windowing
 491             // system sets inappropriate size for this window, we can
 492             // do nothing but accept it.
 493             Rectangle newBounds = newDimensions.getBounds();
 494             Insets insets = newDimensions.getInsets();
 495             // Inherit isClientSizeSet from newDimensions
 496             if (newDimensions.isClientSizeSet()) {
 497                 newBounds = new Rectangle(newBounds.x, newBounds.y,
 498                                           newBounds.width - insets.left - insets.right,
 499                                           newBounds.height - insets.top - insets.bottom);
 500             }
 501             newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet());
 502         }
 503         XToolkit.awtLock();
 504         try {
 505             if (!isReparented() || !isVisible()) {
 506                 insLog.log(Level.FINE, "- not reparented({0}) or not visible({1}), default reshape",
 507                            new Object[] {Boolean.valueOf(isReparented()), Boolean.valueOf(visible)});
 508 
 509                 // Fix for 6323293.
 510                 // This actually is needed to preserve compatibility with previous releases -
 511                 // some of licensees are expecting componentMoved event on invisible one while
 512                 // its location changes.































 513                 Point oldLocation = getLocation();




 514 
 515                 Point newLocation = new Point(ComponentAccessor.getX((Component)target),
 516                                               ComponentAccessor.getY((Component)target));

 517 
 518                 if (!newLocation.equals(oldLocation)) {
 519                     handleMoved(newDimensions);
 520                 }
 521 
 522                 dimensions = new WindowDimensions(newDimensions);
 523                 updateSizeHints(dimensions);
 524                 Rectangle client = dimensions.getClientRect();
 525                 checkShellRect(client);
 526                 setShellBounds(client);
 527                 if (content != null &&
 528                     !content.getSize().equals(newDimensions.getSize()))
 529                 {
 530                     reconfigureContentWindow(newDimensions);





 531                 }


 532                 return;
 533             }
 534 
 535             int wm = XWM.getWMID();
 536             updateChildrenSizes();
 537             applyGuessedInsets();










 538 
 539             Rectangle shellRect = newDimensions.getClientRect();
 540 
 541             if (gravityBug()) {
 542                 Insets in = newDimensions.getInsets();
 543                 shellRect.translate(in.left, in.top);
 544             }
 545 
 546             if ((op & NO_EMBEDDED_CHECK) == 0 && isEmbedded()) {
 547                 shellRect.setLocation(0, 0);
 548             }
 549 
 550             checkShellRectSize(shellRect);
 551             if (!isEmbedded()) {
 552                 checkShellRectPos(shellRect);
 553             }
 554 
 555             op = op & ~NO_EMBEDDED_CHECK;
 556 
 557             if (op == SET_LOCATION) {
 558                 setShellPosition(shellRect);
 559             } else if (isResizable()) {
 560                 if (op == SET_BOUNDS) {
 561                     setShellBounds(shellRect);
 562                 } else {
 563                     setShellSize(shellRect);
 564                 }
 565             } else {
 566                 XWM.setShellNotResizable(this, newDimensions, shellRect, true);
 567                 if (op == SET_BOUNDS) {
 568                     setShellPosition(shellRect);
 569                 }
 570             }
 571 
 572             reconfigureContentWindow(newDimensions);
 573         } finally {
 574             XToolkit.awtUnlock();
 575         }
 576     }
 577 



 578     /**
 579      * @param x, y, width, heith - dimensions of the window with insets
 580      */
 581     private void reshape(int x, int y, int width, int height, int operation,
 582                          boolean userReshape)
 583     {
 584         Rectangle newRec;
 585         boolean setClient = false;
 586         WindowDimensions dims = new WindowDimensions(dimensions);
 587         switch (operation & (~NO_EMBEDDED_CHECK)) {
 588           case SET_LOCATION:
 589               // Set location always sets bounds location. However, until the window is mapped we
 590               // should use client coordinates
 591               dims.setLocation(x, y);
 592               break;
 593           case SET_SIZE:
 594               // Set size sets bounds size. However, until the window is mapped we
 595               // should use client coordinates
 596               dims.setSize(width, height);
 597               break;
 598           case SET_CLIENT_SIZE: {
 599               // Sets client rect size. Width and height contain insets.
 600               Insets in = currentInsets;



 601               width -= in.left+in.right;
 602               height -= in.top+in.bottom;
 603               dims.setClientSize(width, height);

 604               break;
 605           }
 606           case SET_BOUNDS:
 607           default:
 608               dims.setLocation(x, y);
 609               dims.setSize(width, height);
 610               break;
 611         }
 612         if (insLog.isLoggable(Level.FINE)) insLog.log(Level.FINE, "For the operation {0} new dimensions are {1}",
 613                                                       new Object[] {operationToString(operation), dims});
 614 
 615         reshape(dims, operation, userReshape);
 616     }
 617 
 618     // This method gets overriden in XFramePeer & XDialogPeer.
 619     abstract boolean isTargetUndecorated();
 620 
 621     /**
 622      * @see java.awt.peer.ComponentPeer#setBounds


 623      */
 624     public void setBounds(int x, int y, int width, int height, int op) {
 625         // TODO: Rewrite with WindowDimensions
 626         reshape(x, y, width, height, op, true);
 627         validateSurface();
 628     }
 629 
 630     // Coordinates are that of the shell
 631     void reconfigureContentWindow(WindowDimensions dims) {
 632         if (content == null) {
 633             insLog.fine("WARNING: Content window is null");
 634             return;
 635         }
 636         content.setContentBounds(dims);
 637     }
 638 
 639     boolean no_reparent_artifacts = false;
 640     public void handleConfigureNotifyEvent(XEvent xev) {
 641         assert (SunToolkit.isAWTLockHeldByCurrentThread());
 642         XConfigureEvent xe = xev.get_xconfigure();
 643         insLog.log(Level.FINE, "Configure notify {0}", new Object[] {xe});
 644 
 645         // XXX: should really only consider synthetic events, but
 646         if (isReparented()) {
 647             configure_seen = true;




 648         }
 649 
 650         if (!isMaximized()
 651             && (xe.get_serial() == reparent_serial || xe.get_window() != getShell())
 652             && !no_reparent_artifacts)
 653         {
 654             insLog.fine("- reparent artifact, skipping");
 655             return;
 656         }
 657         no_reparent_artifacts = false;
 658 
 659         /**
 660          * When there is a WM we receive some CN before being visible and after.
 661          * We should skip all CN which are before being visible, because we assume
 662          * the gravity is in action while it is not yet.
 663          *
 664          * When there is no WM we receive CN only _before_ being visible.
 665          * We should process these CNs.
 666          */
 667         if (!isVisible() && XWM.getWMID() != XWM.NO_WM) {
 668             insLog.fine(" - not visible, skipping");
 669             return;

 670         }
 671 
 672         /*
 673          * Some window managers configure before we are reparented and
 674          * the send event flag is set! ugh... (Enlighetenment for one,
 675          * possibly MWM as well).  If we haven't been reparented yet
 676          * this is just the WM shuffling us into position.  Ignore
 677          * it!!!! or we wind up in a bogus location.
 678          */
 679         int runningWM = XWM.getWMID();
 680         if (insLog.isLoggable(Level.FINE)) {
 681             insLog.log(Level.FINE, "reparented={0}, visible={1}, WM={2}, decorations={3}",
 682                     new Object[] {isReparented(), isVisible(), runningWM, getDecorations()});
 683         }
 684         if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
 685                 &&  !XWM.isNonReparentingWM()
 686                 && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
 687             insLog.fine("- visible but not reparented, skipping");
 688             return;



 689         }
 690         //Last chance to correct insets
 691         if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
 692             long parent = XlibUtil.getParentWindow(window);
 693             Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
 694             if (insLog.isLoggable(Level.FINER)) {
 695                 if (correctWM != null) {
 696                     insLog.finer("Configure notify - insets : " + correctWM);
 697                 } else {
 698                     insLog.finer("Configure notify - insets are still not available");




 699                 }






 700             }
 701             if (correctWM != null) {
 702                 handleCorrectInsets(correctWM);
 703             } else {
 704                 //Only one attempt to correct insets is made (to lower risk)
 705                 //if insets are still not available we simply set the flag
 706                 insets_corrected = true;
 707             }



 708         }
 709 
 710         updateChildrenSizes();


 711 
 712         // Bounds of the window
 713         Rectangle targetBounds = new Rectangle(ComponentAccessor.getX((Component)target),
 714                 ComponentAccessor.getY((Component)target),
 715                 ComponentAccessor.getWidth((Component)target),
 716                 ComponentAccessor.getHeight((Component)target));
 717 
 718         Point newLocation = targetBounds.getLocation();
 719         if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
 720             // Location, Client size + insets
 721             newLocation = new Point(xe.get_x() - currentInsets.left, xe.get_y() - currentInsets.top);
 722         } else {
 723             // CDE/MWM/Metacity/Sawfish bug: if shell is resized using
 724             // top or left border, we don't receive synthetic
 725             // ConfigureNotify, only the one from X with zero
 726             // coordinates.  This is the workaround to get real
 727             // location, 6261336
 728             switch (XWM.getWMID()) {
 729                 case XWM.CDE_WM:
 730                 case XWM.MOTIF_WM:
 731                 case XWM.METACITY_WM:
 732                 case XWM.SAWFISH_WM:
 733                 {
 734                     Point xlocation = queryXLocation();
 735                     if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "New X location: {0}", new Object[]{xlocation});
 736                     if (xlocation != null) {
 737                         newLocation = xlocation;




 738                     }
 739                     break;








 740                 }
 741                 default:
 742                     break;
 743             }




 744         }
 745 
 746         WindowDimensions newDimensions =
 747                 new WindowDimensions(newLocation,
 748                 new Dimension(xe.get_width(), xe.get_height()),
 749                 copy(currentInsets),
 750                 true);
 751 
 752         insLog.log(Level.FINER, "Insets are {0}, new dimensions {1}",
 753                 new Object[] {currentInsets, newDimensions});











 754 
 755         checkIfOnNewScreen(newDimensions.getBounds());
 756 
 757         Point oldLocation = getLocation();
 758         dimensions = newDimensions;
 759         if (!newLocation.equals(oldLocation)) {
 760             handleMoved(newDimensions);
 761         }
 762         reconfigureContentWindow(newDimensions);
 763         updateChildrenSizes();
 764 
 765         repositionSecurityWarning();

















































































































 766     }
 767 
 768     private void checkShellRectSize(Rectangle shellRect) {
 769         if (shellRect.width < 0) {
 770             shellRect.width = 1;
 771         }
 772         if (shellRect.height < 0) {
 773             shellRect.height = 1;
 774         }
 775     }
 776 
 777     private void checkShellRectPos(Rectangle shellRect) {
 778         int wm = XWM.getWMID();
 779         if (wm == XWM.MOTIF_WM || wm == XWM.CDE_WM) {
 780             if (shellRect.x == 0 && shellRect.y == 0) {
 781                 shellRect.x = shellRect.y = 1;
 782             }
 783         }
 784     }
 785 


 815     }
 816     public void setShellPosition(Rectangle rec) {
 817         if (insLog.isLoggable(Level.FINE)) insLog.fine("Setting shell position on " +
 818                                                        this + " to " + rec);
 819         XToolkit.awtLock();
 820         try {
 821             updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 822             XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
 823         }
 824         finally {
 825             XToolkit.awtUnlock();
 826         }
 827     }
 828 
 829     void initResizability() {
 830         setResizable(winAttr.initialResizability);
 831     }
 832     public void setResizable(boolean resizable) {
 833         int fs = winAttr.functions;
 834         if (!isResizable() && resizable) {
 835             currentInsets = new Insets(0, 0, 0, 0);
 836             resetWMSetInsets();
 837             if (!isEmbedded()) {
 838                 setReparented(false);
 839             }
 840             winAttr.isResizable = resizable;
 841             if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
 842                 fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
 843             } else {
 844                 fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
 845             }
 846             winAttr.functions = fs;
 847             XWM.setShellResizable(this);
 848         } else if (isResizable() && !resizable) {
 849             currentInsets = new Insets(0, 0, 0, 0);
 850             resetWMSetInsets();
 851             if (!isEmbedded()) {
 852                 setReparented(false);
 853             }
 854             winAttr.isResizable = resizable;
 855             if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
 856                 fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
 857             } else {
 858                 fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
 859             }
 860             winAttr.functions = fs;
 861             XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false);
 862         }
 863     }
 864 
 865     Rectangle getShellBounds() {
 866         return dimensions.getClientRect();
 867     }
 868 
 869     public Rectangle getBounds() {
 870         return dimensions.getBounds();
 871     }
 872 
 873     public Dimension getSize() {


 894     public int getAbsoluteY() {
 895         // NOTE: returning this peer's location which is shell location
 896         return dimensions.getScreenBounds().y;
 897     }
 898 
 899     public int getWidth() {
 900         return getSize().width;
 901     }
 902 
 903     public int getHeight() {
 904         return getSize().height;
 905     }
 906 
 907     final public WindowDimensions getDimensions() {
 908         return dimensions;
 909     }
 910 
 911     public Point getLocationOnScreen() {
 912         XToolkit.awtLock();
 913         try {
 914             if (configure_seen) {
 915                 return toGlobal(0,0);
 916             } else {
 917                 Point location = target.getLocation();
 918                 if (insLog.isLoggable(Level.FINE))
 919                     insLog.log(Level.FINE, "getLocationOnScreen {0} not reparented: {1} ",
 920                                new Object[] {this, location});

 921                 return location;
 922             }
 923         } finally {
 924             XToolkit.awtUnlock();
 925         }
 926     }
 927 
 928 
 929 /***************************************************************************************
 930  *              END            OF             I N S E T S   C O D E
 931  **************************************************************************************/
 932 
 933     protected boolean isEventDisabled(XEvent e) {
 934         switch (e.get_type()) {
 935             // Do not generate MOVED/RESIZED events since we generate them by ourselves
 936           case XConstants.ConfigureNotify:
 937               return true;
 938           case XConstants.EnterNotify:
 939           case XConstants.LeaveNotify:
 940               // Disable crossing event on outer borders of Frame so


1040     final void dumpMe() {
1041         System.err.println(">>> Peer: " + x + ", " + y + ", " + width + ", " + height);
1042     }
1043 
1044     final void dumpTarget() {
1045         int getWidth = ComponentAccessor.getWidth((Component)target);
1046         int getHeight = ComponentAccessor.getHeight((Component)target);
1047         int getTargetX = ComponentAccessor.getX((Component)target);
1048         int getTargetY = ComponentAccessor.getY((Component)target);
1049         System.err.println(">>> Target: " + getTargetX + ", " + getTargetY + ", " + getWidth + ", " + getHeight);
1050     }
1051 
1052     final void dumpShell() {
1053         dumpWindow("Shell", getShell());
1054     }
1055     final void dumpContent() {
1056         dumpWindow("Content", getContentWindow());
1057     }
1058     final void dumpParent() {
1059         long parent = XlibUtil.getParentWindow(getShell());
1060         if (parent != 0)
1061         {
1062             dumpWindow("Parent", parent);
1063         }
1064         else
1065         {
1066             System.err.println(">>> NO PARENT");
1067         }
1068     }
1069 
1070     final void dumpWindow(String id, long window) {
1071         XWindowAttributes pattr = new XWindowAttributes();
1072         try {
1073             XToolkit.awtLock();
1074             try {
1075                 int status =
1076                     XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
1077                                                      window, pattr.pData);
1078             }
1079             finally {
1080                 XToolkit.awtUnlock();


1083                                + ", " + pattr.get_y() + ", " + pattr.get_width()
1084                                + ", " + pattr.get_height());
1085         } finally {
1086             pattr.dispose();
1087         }
1088     }
1089 
1090     final void dumpAll() {
1091         dumpTarget();
1092         dumpMe();
1093         dumpParent();
1094         dumpShell();
1095         dumpContent();
1096     }
1097 
1098     boolean isMaximized() {
1099         return false;
1100     }
1101 
1102     boolean isOverrideRedirect() {
1103 //        return false;
1104         return ((XToolkit)Toolkit.getDefaultToolkit()).isOverrideRedirect((Window)target);
1105     }
1106 
1107     public boolean requestWindowFocus(long time, boolean timeProvided) {
1108         focusLog.fine("Request for decorated window focus");
1109         // If this is Frame or Dialog we can't assure focus request success - but we still can try
1110         // If this is Window and its owner Frame is active we can be sure request succedded.
1111         Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
1112         Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
1113 
1114         focusLog.log(Level.FINER, "Current window is: active={0}, focused={1}",
1115                      new Object[]{ Boolean.valueOf(target == activeWindow),
1116                                    Boolean.valueOf(target == focusedWindow)});
1117 
1118         XWindowPeer toFocus = this;
1119         while (toFocus.nextTransientFor != null) {
1120             toFocus = toFocus.nextTransientFor;
1121         }
1122         if (toFocus == null || !toFocus.focusAllowedFor()) {
1123             // This might change when WM will have property to determine focus policy.


   1 /*
   2  * Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 package sun.awt.X11;
  26 
  27 import java.awt.*;
  28 
  29 import java.awt.event.ComponentEvent;
  30 import java.awt.event.InvocationEvent;
  31 import java.awt.event.WindowEvent;
  32 
  33 import java.util.logging.Level;
  34 import java.util.logging.Logger;
  35 
  36 import sun.awt.AWTAccessor;
  37 import sun.awt.ComponentAccessor;
  38 import sun.awt.SunToolkit;
  39 
  40 abstract class XDecoratedPeer extends XWindowPeer {
  41     private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer");
  42     private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
  43     private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
  44     private static final Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XDecoratedPeer");
  45 





  46     XIconWindow iconWindow;
  47 
  48     /**
  49      * The dimensions of the window.
  50      *
  51      * The entity encapsulates information about the bounds and the insets of
  52      * the window. The value is initialized in the preInit() method with the
  53      * bounds of the window as known on the shared level. Further updates
  54      * should be performed with the reportReshape() method only.
  55      */
  56     protected WindowDimensions dimensions;
  57 
  58     XContentWindow content;

  59     XFocusProxyWindow focusProxy;
  60 
  61     XDecoratedPeer(Window target) {
  62         super(target);
  63     }
  64 
  65     XDecoratedPeer(XCreateWindowParams params) {
  66         super(params);
  67     }
  68 
  69     public long getShell() {
  70         return window;
  71     }
  72 
  73     public long getContentWindow() {
  74         return (content == null) ? window : content.getWindow();
  75     }
  76 
  77     void preInit(XCreateWindowParams params) {
  78         super.preInit(params);
  79         winAttr.initialFocus = true;
  80 



  81         Rectangle bounds = (Rectangle)params.get(BOUNDS);
  82         dimensions = new WindowDimensions(bounds, getNativeInsets(), false);
  83         params.put(BOUNDS, dimensions.getClientRect());
  84         insLog.log(Level.FINE, "Initial dimensions {0}", new Object[] { dimensions });
  85 
  86         // Deny default processing of these events on the shell - proxy will take care of
  87         // them instead
  88         Long eventMask = (Long)params.get(EVENT_MASK);
  89         params.add(EVENT_MASK, Long.valueOf(eventMask.longValue() & ~(XConstants.FocusChangeMask | XConstants.KeyPressMask | XConstants.KeyReleaseMask)));
  90     }
  91 
  92     void postInit(XCreateWindowParams params) {
  93         super.postInit(params);
  94         // The lines that follow need to be in a postInit, so they
  95         // happen after the X window is created.
  96         initResizability();
  97         updateSizeHints(dimensions);

  98 
  99         content = XContentWindow.createContent(this);
 100 
 101         if (warningWindow != null) {
 102             warningWindow.toFront();
 103         }
 104         focusProxy = createFocusProxy();
 105     }
 106 
 107     void setIconHints(java.util.List<XIconInfo> icons) {
 108         if (!XWM.getWM().setNetWMIcon(this, icons)) {
 109             if (icons.size() > 0) {
 110                 if (iconWindow == null) {
 111                     iconWindow = new XIconWindow(this);
 112                 }
 113                 iconWindow.setIconImages(icons);
 114             }
 115         }
 116     }
 117 
 118     public void updateMinimumSize() {
 119         super.updateMinimumSize();
 120         updateMinSizeHints(getNativeInsets());
 121     }
 122 
 123     private void updateMinSizeHints(Insets insets) {
 124         if (isResizable()) {
 125             Dimension minimumSize = getTargetMinimumSize();
 126             if (minimumSize != null) {

 127                 int minWidth = minimumSize.width - insets.left - insets.right;
 128                 int minHeight = minimumSize.height - insets.top - insets.bottom;
 129                 if (minWidth < 0) minWidth = 0;
 130                 if (minHeight < 0) minHeight = 0;
 131                 setSizeHints(XUtilConstants.PMinSize | (isLocationByPlatform()?0:(XUtilConstants.PPosition | XUtilConstants.USPosition)),
 132                              getX(), getY(), minWidth, minHeight);
 133                 if (isVisible()) {
 134                     Rectangle bounds = getShellBounds();
 135                     int nw = (bounds.width < minWidth) ? minWidth : bounds.width;
 136                     int nh = (bounds.height < minHeight) ? minHeight : bounds.height;
 137                     if (nw != bounds.width || nh != bounds.height) {
 138                         setShellSize(new Rectangle(0, 0, nw, nh));
 139                     }
 140                 }
 141             } else {
 142                 boolean isMinSizeSet = isMinSizeSet();
 143                 XWM.removeSizeHints(this, XUtilConstants.PMinSize);
 144                 /* Some WMs need remap to redecorate the window */
 145                 if (isMinSizeSet && isShowing() && XWM.needRemap(this)) {
 146                     /*


 214     // NOTE: This method may be called by privileged threads.
 215     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
 216     public void handleDeiconify() {
 217         postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_DEICONIFIED));
 218     }
 219 
 220     public void handleFocusEvent(XEvent xev) {
 221         super.handleFocusEvent(xev);
 222         XFocusChangeEvent xfe = xev.get_xfocus();
 223 
 224         // If we somehow received focus events forward it instead to proxy
 225         // FIXME: Shouldn't we instead check for inferrior?
 226         focusLog.finer("Received focus event on shell: " + xfe);
 227 //         focusProxy.xRequestFocus();
 228    }
 229 
 230 /***************************************************************************************
 231  *                             I N S E T S   C O D E
 232  **************************************************************************************/
 233 



 234 
 235     /**
 236     * Current native insets of the window on the desktop.
 237     * When it's noticed the insets might have been changed (like when we
 238     * receive a ReparentNotify), the value must be reset to null by the
 239     * setNativeInsets(null) call.
 240     *
 241     * Synchronization: the awtLock is used. This should have been the state
 242     * lock instead, but the retrieveNativeInsets() uses the awtLock, and the
 243     * later must be always taken before the state lock.
 244     *
 245     * The field MUST NOT be used directly. Use get/setNativeInsets() instead.
 246     */
 247     private Insets nativeInsets = null;
 248 
 249     /**
 250     * Gets the current native insets.
 251     * This method may only return null if the fallBackToDefault is false.
 252     */
 253     private Insets getNativeInsets(boolean retrieve, boolean fallBackToDefault) {
 254         if (isTargetUndecorated() || isEmbedded() || !XWM.isRunning())
 255         {
 256             return (Insets)ZERO_INSETS.clone();
 257         }
 258         if (getWindow() == XConstants.None) {
 259             return getDefaultInsets();

 260         }
 261         XToolkit.awtLock();
 262         try {
 263             if (nativeInsets == null && retrieve) {
 264                 retrieveNativeInsets();



 265             }
 266             return nativeInsets == null ?
 267                 (fallBackToDefault ? getDefaultInsets() : null) :
 268                 (Insets)nativeInsets.clone();
 269         } finally {
 270             XToolkit.awtUnlock();
 271         }





 272     }
 273 
 274     /**
 275     * Gets the current native insets.
 276     */
 277     public Insets getNativeInsets() {
 278         return getNativeInsets(true, true);
 279     }
 280 
 281     @Override
 282     public Insets getInsets() {
 283         Insets insets = getNativeInsets();
 284         insets.top += getMenuBarHeight();
 285         if (insLog.isLoggable(Level.FINEST)) {
 286             insLog.log(Level.FINEST, "Get insets returns {0}",
 287                     new Object[] {insets});
 288         }
 289         return insets;
 290     }
 291 
 292     /**
 293      * Returns the insets that the window probably will get.
 294      */
 295     private Insets getDefaultInsets() {
 296         Insets insets = XWM.getWM().getDefaultInsets();
 297         return (Insets)(insets == null ? DEFAULT_INSETS : insets).clone();
 298     }
 299 
 300     /**
 301      * Get rid of insane insets.
 302      * The operation is performed in place - the given object gets modified.
 303      */
 304     private static Insets sanitize(Insets insets) {
 305         //XXX: Perhaps using the marginal values instead of the default would
 306         //     make more sense?
 307         if (insets.top > 64 || insets.top < 0) {
 308             insets.top = DEFAULT_INSETS.top;
 309         }
 310         if (insets.left > 32 || insets.left < 0) {
 311             insets.left = DEFAULT_INSETS.left;
 312         }
 313         if (insets.right > 32 || insets.right < 0) {
 314             insets.right = DEFAULT_INSETS.right;
 315         }
 316         if (insets.bottom > 32 || insets.bottom < 0) {
 317             insets.bottom = DEFAULT_INSETS.bottom;
 318         }
 319         return insets;
 320     }
 321 
 322     private void setNativeInsets(Insets insets) {





 323         XToolkit.awtLock();
 324         try {
 325             nativeInsets = insets == null ? null :
 326                 sanitize((Insets)insets.clone());
 327         } finally {
 328             XToolkit.awtUnlock();
 329         }

 330     }








 331 
 332     public static final Insets DEFAULT_INSETS = new Insets(25, 5, 5, 5);
 333     public static final Insets ZERO_INSETS = new Insets(0, 0, 0, 0);
 334 
 335     /**
 336      * Retrieve the current insets of the window.
 337      *
 338      * This method must only be called by the getNativeInsets() method. DO NOT
 339      * call this method directly. If the insets need to be updated, nullify
 340      * them using the setNativeInsets(null) method.
 341      */
 342     private void retrieveNativeInsets() {
 343         long window = getWindow();
 344 
 345         if (XWM.requestWMExtents(window)) {
 346             XWM.waitForExtentsUpdateEvent();

 347         }
 348 
 349         // Some WMs may provide the extents via a property, but do not require
 350         // a request to update them. Hence try getting them unconditionally.
 351         // We could use the XEvent returned by the waitForExtentsUpdateEvent()
 352         // above, though that doesn't seem to make much sense.
 353         Insets insets = XWM.getInsetsFromExtents(window);
 354         if (insets != null) {
 355             setNativeInsets(insets);







 356             return;
 357         }


 358 
 359         // The window manager is unable to report any extents, so we need to
 360         // calculate them ourselves.
 361         Rectangle winRect = XlibUtil.getWindowGeometry(
 362                 window, XlibWrapper.larg1);
 363         if (winRect == null) {
 364             // Some error occured
 365             return;
 366         }
 367         // The root window must be got immediately after the previous
 368         // getWindowGeometry() call.
 369         long root = Native.getWindow(XlibWrapper.larg1); 
 370 
 371         long parent = getNativeParent();
 372         if (parent == XConstants.None || parent == root) {
 373             // Non-reparenting WM. Assume the insets are zero.
 374             setNativeInsets(ZERO_INSETS);
 375             return;
 376         }
 377 
 378         Rectangle parentRect = XlibUtil.getWindowGeometry(parent);
 379         if (parentRect == null) {
 380             // Some error again
 381             return;
 382         }
 383 
 384         long grand_parent = XlibUtil.getParentWindow(parent);
 385         if (grand_parent == XConstants.None || grand_parent == root ||
 386                 (winRect.x != 0 || winRect.y != 0 ||
 387                  winRect.width != parentRect.width ||
 388                  winRect.height != parentRect.height))
 389         {
 390             // Single-reparenting WM
 391             // Either there's no a valid grand-parent, or the direct parent
 392             // has greater bounds than the window itself.
 393             setNativeInsets(calculateInsets(winRect, parentRect));
 394         } else {
 395             // Double-reparenting WM
 396             // There's a valid grand-parent. The bounds of the direct
 397             // parent are equal to the bounds of the window itself.
 398             Rectangle grandParentRect = XlibUtil.getWindowGeometry(
 399                     grand_parent);
 400             if (grandParentRect == null) {
 401                 // One more error condition. This time we fall back to the
 402                 // single-reparenting case, though this will produce
 403                 // ZERO_INSETS actually...
 404                 setNativeInsets(calculateInsets(winRect, parentRect));
 405             } else {
 406                 setNativeInsets(calculateInsets(parentRect, grandParentRect));
 407             }


 408         }
 409     }
 410 
 411     /**
 412      * Calculates the insets for the given interior and exterior rectangles.
 413      * Only positive insets are allowed. If the interior rectangle is bigger
 414      * than the exterior one, the negative inset values will be ignored,
 415      * and zero value used instead.

 416      */
 417     private static Insets calculateInsets(Rectangle interior, Rectangle exterior) {
 418         return new Insets(
 419                 Math.max(interior.y, 0),
 420                 Math.max(interior.x, 0),
 421                 Math.max(exterior.height - interior.height - interior.y, 0),
 422                 Math.max(exterior.width - interior.width - interior.x, 0));




 423     }

 424 
 425     /**
 426      * Applies the new insets.
 427      */
 428     private void setInsets(Insets insets) {
 429         setNativeInsets(insets);
 430 
 431         WindowDimensions dims = new WindowDimensions(dimensions);
 432         dims.setInsets(insets);
 433         reportOrAdjust(dims, false);
 434     }
 435 
 436     @Override
 437     public void handlePropertyNotify(XEvent xev) {
 438         super.handlePropertyNotify(xev);
 439 
 440         XPropertyEvent ev = xev.get_xproperty();
 441         if (XWM.isExtentsPropertyAtom(ev.get_atom())) {
 442             Insets insets = XWM.getInsetsFromProp(getWindow(),
 443                     XAtom.get(ev.get_atom()));
 444             if (insLog.isLoggable(Level.FINE)) {
 445                 insLog.fine("" + insets);
 446             }
 447             if (insets != null) {
 448                 setInsets(insets);
 449             }


 450         }
 451     }
 452 
 453     // The serial of the last received ReparentNotify event
 454     private long reparentNotifySerial = 0;
 455 
 456     // The number of processed ConfigureNotify events with the same serial
 457     // as reparentNotifySerial.
 458     private int numOfConfigureNotifyJustAfterReparentNotify = 0;
 459 
 460     @Override
 461     public void handleReparentNotifyEvent(XEvent xev) {
 462         super.handleReparentNotifyEvent(xev);
 463 
 464         XReparentEvent  xe = xev.get_xreparent();
 465         if (insLog.isLoggable(Level.FINE)) {
 466             insLog.fine(xe.toString());
 467         }
 468 
 469         if (xe.get_window() != getWindow()) {
 470             return;
 471         }
 472 
 473         if (!isParented()) {
 474             if (isVisible()) {
 475                 // Either the WM or the embedder exited
 476                 XWM.getWM().unshadeKludge(this);
 477                 if (!isEmbedded()) {
 478                     XWM.reset();





 479                 }
 480                 setInsets(null);
 481             } //else: The window just got hidden
 482         } else {
 483             // We just got parented: prepare stuff to recalculate the insets,
 484             // and to readjust the bounds if needed
 485             reparentNotifySerial = xe.get_serial();
 486             numOfConfigureNotifyJustAfterReparentNotify = 0;
 487 
 488             setNativeInsets(null);
 489             needToAdjustBounds();
 490         }
 491     }
 492 
 493     protected boolean isInitialReshape() {
 494         return false;
 495     }
 496 
 497     public void handleMoved(Point loc) {
 498         ComponentAccessor.setX((Component)target, loc.x);
 499         ComponentAccessor.setY((Component)target, loc.y);
 500         postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
 501     }
 502 
 503 
 504     public void revalidate() {
 505         XToolkit.executeOnEventHandlerThread(target, new Runnable() {
 506                 public void run() {
 507                     target.invalidate();
 508                     target.validate();
 509                 }
 510             });
 511     }
 512 
















 513     boolean gravityBug() {
 514         return XWM.configureGravityBuggy();
 515     }
 516 
 517     // The height of area used to display current active input method
 518     int getInputMethodHeight() {
 519         return 0;
 520     }
 521 
 522     void updateSizeHints(WindowDimensions dims) {
 523         Rectangle rec = dims.getClientRect();
 524         checkShellRect(rec);
 525         updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 526     }
 527 
 528     void updateSizeHints() {
 529         updateSizeHints(dimensions);
 530     }
 531 
 532     // Coordinates are that of the target
 533     // Called only on Toolkit thread
 534     private void reshape(WindowDimensions newDimensions, int op)

 535     {
 536         if (insLog.isLoggable(Level.FINE)) {
 537             insLog.fine("Reshaping " + this + " to " + newDimensions +
 538                     "; op " + operationToString(op));














 539         }
 540         XToolkit.awtLock();
 541         try {
 542             if (!isVisible()) {
 543                 Rectangle client = newDimensions.getClientRect();
 544                 checkShellRect(client);
 545                 setShellBounds(client);
 546 
 547                 reportReshape(newDimensions);
 548             } else {
 549                 requestReshape(newDimensions, op);
 550             }
 551         } finally {
 552             XToolkit.awtUnlock();
 553         }
 554     }
 555 
 556     /**
 557      * Sets window dimensions and propagates the changes to the target sending
 558      * corresponding events if needed.
 559      * 
 560      * MUST be invoked under the AWTLock.
 561      */
 562     private void reportReshape(WindowDimensions newDims) {
 563         if (insLog.isLoggable(Level.FINE)) {
 564             insLog.fine("" + newDims);
 565         }
 566 
 567         final Insets insets = newDims.getInsets();
 568         if (!insets.equals(dimensions.getInsets())) {
 569             // Recalculate the minimum size of the client area
 570             updateMinSizeHints(insets);
 571         }
 572 
 573         // If the client area size changes, we need to revalidate the target.
 574         // This may happen in the XContentWindow.setContentBounds(). If this
 575         // does not happen there, we need to dispatch the operation here.
 576         final boolean needRevalidate =
 577             !dimensions.getClientSize().equals(newDims.getClientSize());
 578 
 579         checkIfOnNewScreen(newDims.getBounds());
 580 
 581         Point oldLocation = getLocation();
 582         dimensions = newDims;
 583         if (!getLocation().equals(oldLocation)) {
 584             handleMoved(getLocation());
 585         }
 586 
 587         if (!reconfigureContentWindow(dimensions) && needRevalidate) {
 588             revalidate();
 589         }
 590 
 591         updateChildrenSizes();
 592         repositionSecurityWarning();
 593     }
 594 
 595     private void reportOrAdjust(WindowDimensions newDims,
 596             boolean handlingConfigureNotify)





 597     {
 598         if (dimensions.equals(newDims) && !areBoundsAdjusting()) {
 599             // If nothing has changed and we're already adjusted, return
 600             if (insLog.isLoggable(Level.FINE)) {
 601                 insLog.fine("Ignored: nothing changed: " + newDims);
 602             }
 603             return;
 604         }
 605         if (adjustBounds(newDims, handlingConfigureNotify)) {
 606             // We expect another ConfigureNotify
 607             return;
 608         }
 609 
 610         reportReshape(newDims);
 611     }
 612 
 613     /**
 614      * Requests the system to reshape the window.
 615      * 
 616      * MUST be invoked under the AWTLock.
 617      */
 618     private void requestReshape(WindowDimensions newDimensions, int op) {
 619         if (insLog.isLoggable(Level.FINE)) {
 620             insLog.fine("Request reshape: " + newDimensions + "; op: " +
 621                     operationToString(op));
 622         }
 623 
 624         Rectangle shellRect = newDimensions.getClientRect();
 625 
 626         if (gravityBug()) {
 627             Insets in = newDimensions.getInsets();
 628             shellRect.translate(in.left, in.top);
 629         }
 630 
 631         if ((op & NO_EMBEDDED_CHECK) == 0 && isEmbedded()) {
 632             shellRect.setLocation(0, 0);
 633         }
 634 
 635         checkShellRectSize(shellRect);
 636         if (!isEmbedded()) {
 637             checkShellRectPos(shellRect);
 638         }
 639 
 640         op = op & ~NO_EMBEDDED_CHECK;
 641 
 642         if (op == SET_LOCATION) {
 643             setShellPosition(shellRect);
 644         } else if (isResizable()) {
 645             if (op == SET_BOUNDS) {
 646                 setShellBounds(shellRect);
 647             } else {
 648                 setShellSize(shellRect);
 649             }
 650         } else {
 651             XWM.setShellNotResizable(this, newDimensions, shellRect, true);
 652             if (op == SET_BOUNDS) {
 653                 setShellPosition(shellRect);
 654             }
 655         }





 656     }
 657 
 658     // This method gets overriden in XFramePeer & XDialogPeer.
 659     abstract boolean isTargetUndecorated();
 660 
 661     /**
 662      * @see java.awt.peer.ComponentPeer#setBounds
 663      */
 664     public void setBounds(int x, int y, int width, int height, int operation) {




 665         WindowDimensions dims = new WindowDimensions(dimensions);
 666         switch (operation & (~NO_EMBEDDED_CHECK)) {
 667           case SET_LOCATION:
 668               // Set location always sets bounds location. However, until the window is mapped we
 669               // should use client coordinates
 670               dims.setLocation(x, y);
 671               break;
 672           case SET_SIZE:
 673               // Set size sets bounds size. However, until the window is mapped we
 674               // should use client coordinates
 675               dims.setSize(width, height);
 676               break;
 677           case SET_CLIENT_SIZE: {
 678               // Sets client rect size. Width and height contain insets.
 679               // Also update the insets to the latest known value to decrease
 680               // (or even eliminate) the bounds adjustment after showing
 681               // the window.
 682               Insets in = getNativeInsets();
 683               width -= in.left+in.right;
 684               height -= in.top+in.bottom;
 685               dims.setClientSize(width, height);
 686               dims.setInsets(in);
 687               break;
 688           }
 689           case SET_BOUNDS:
 690           default:
 691               dims.setLocation(x, y);
 692               dims.setSize(width, height);
 693               break;
 694         }
 695         reshape(dims, operation);
 696         validateSurface();


 697     }
 698 



 699     /**
 700      * Sets the content window bounds.
 701      *
 702      * @return whether a COMPONENT_RESIZED has been sent
 703      */
 704     boolean reconfigureContentWindow(WindowDimensions dims) {







 705         if (content == null) {
 706             insLog.fine("WARNING: Content window is null");
 707             return false;
 708         }
 709         return content.setContentBounds(dims);
 710     }
 711 
 712     /**
 713      * Indicates if the adjustBounds() needs to be invoked.
 714      * Synchronization: state lock.
 715      */
 716     private boolean areBoundsAdjusted = false;
 717 
 718     /**
 719      * Forces the system to re-adjust the bounds of the window after it has
 720      * been finally adopted by the windowing system.
 721      */
 722     private void needToAdjustBounds() {
 723         synchronized (getStateLock()) {
 724             areBoundsAdjusted = false;
 725         }







 726     }

 727 
 728     /**
 729      * Indicates if the window bounds has not yet been finally configured by
 730      * the X server/window manager.




 731      */
 732     public boolean areBoundsAdjusting() {
 733         synchronized (getStateLock()) {
 734             return !areBoundsAdjusted;
 735         }
 736     }
 737 
 738     // XXX: Perhaps the following two might be replaced with Window.isSizeSet,
 739     //      isLocationSet? Just like we have Window.isPacked...
 740     /**
 741      * Indicates if the size hints of the window specify a position requested
 742      * by the user's code.

 743      */
 744     private boolean isUserSpecifiedPositionSet() {
 745         return (getHints().get_flags() &
 746                 (XUtilConstants.USPosition | XUtilConstants.PPosition)) != 0;

 747     }
 748 
 749     /**
 750      * Indicates if the size hints of the window specify a position requested
 751      * by the user's code.
 752      */
 753     private boolean isUserSpecifiedSizeSet() {
 754         return (getHints().get_flags() &
 755                 (XUtilConstants.USSize | XUtilConstants.PSize)) != 0;
 756     }
 757 
 758     /**
 759      * Adjust the bounds of the window.
 760      *
 761      * @return true if an adjustment has taken place. false if the new bounds
 762      *         are OK.
 763      */
 764     private boolean adjustBounds(WindowDimensions newDims,
 765             boolean handlingConfigureNotify)
 766     {
 767         synchronized (getStateLock()) {
 768             if (areBoundsAdjusted) {
 769                 return false;
 770             }
 771             // We have to adjust bounds upon showing once.
 772             // We also may adjust them several times before showing - e.g.
 773             // when we receive the PropertyNotify event with the extents.
 774             if (handlingConfigureNotify && isVisible()) {
 775                 insLog.log(Level.FINE, "Final adjustment");
 776                 areBoundsAdjusted = true;
 777             }






 778         }
 779 
 780         if (isMaximized()) {
 781             return false;
 782         }
 783 
 784         int operation = 0;
 785         boolean isPacked = AWTAccessor.getWindowAccessor().
 786             isPacked((Window)target);
 787 
 788         if (!newDims.getClientSize().equals(dimensions.getClientSize())
 789                 && isPacked)



















 790         {
 791             // The client area size calculated via pack() needs to be preserved
 792             operation = SET_SIZE;
 793         } else
 794         if (!newDims.getSize().equals(dimensions.getSize())
 795                 && isUserSpecifiedSizeSet())
 796         {
 797             // The size set via setSize()/setBounds() needs to be preserved
 798             operation = SET_SIZE;
 799         }
 800 
 801         if (isUserSpecifiedPositionSet() &&
 802                 !newDims.getLocation().equals(dimensions.getLocation()))
 803         {
 804             // The user also requested a specific position
 805             if (operation == 0) {
 806                 operation = SET_LOCATION;
 807             } else {
 808                 operation = SET_BOUNDS;
 809             }


 810         }
 811 
 812         if (operation == 0) {
 813             insLog.fine("No adjustment needed");
 814             return false;
 815         }
 816 
 817         WindowDimensions dims = new WindowDimensions(
 818                 dimensions.getLocation(),
 819                 isPacked ? dimensions.getClientSize() : dimensions.getSize(),
 820                 newDims.getInsets(),
 821                 isPacked);
 822         
 823         if (insLog.isLoggable(Level.FINE)) {
 824             insLog.fine("Request: " + dims + "; operation=" +
 825                     operationToString(operation));
 826         }
 827         requestReshape(dims, operation);
 828         return true;
 829     }
 830 
 831     @Override
 832     public void handleConfigureNotifyEvent(XEvent xev) {
 833         // Note: we don't call super because the XWindowPeer immediately calls
 834         //       the checkIfOnNewScreen() assuming the bounds are correct. This
 835         //       is not always correct for decorated peers.
 836 
 837         XConfigureEvent xe = xev.get_xconfigure();
 838 
 839         // Due to the SubstructureNotifyMask we should process only those
 840         // events that belong to us.
 841         if (xe.get_window() != getWindow()) {
 842             return;
 843         }


 844         
 845         if (insLog.isLoggable(Level.FINE)) {
 846             insLog.fine("" + xe);
 847             insLog.fine("XWM.isRunning: " + XWM.isRunning());
 848         }
 849 
 850         // If there's a WM we have to ignore some events
 851         if (XWM.isRunning()) {
 852             // Ignore any events until after we become visible
 853             if (!isVisible()) {
 854                 insLog.fine("Ignored: Not visible yet");
 855                 needToAdjustBounds();
 856                 return;
 857             }
 858 
 859             // We have not yet been parented by the WM
 860             if (mayBeReparented() && !isTargetUndecorated()) {
 861                 insLog.fine("Ignored: Not parented yet");
 862                 needToAdjustBounds();
 863                 return;
 864             }
 865 
 866             // Just after reparenting we can receive a synthetic and/or real
 867             // event(s).  Since sometimes we need to adjust the bounds of the
 868             // frame, we need to process only one of the events. Justification:
 869             //    1. Both events carry the same information: one from the X
 870             //    server, the other from the WM.
 871             //    2. The adjustment operation is performed only once upon
 872             //    processing the first ConfigureNotify event that is not
 873             //    ignored.
 874             //    3. If the first event causes the adjustment to happen, the
 875             //    second event will be considered as a normal, not ignored
 876             //    event that may generate Java events and set incorrect
 877             //    (not-yet-adjusted) bounds to the frame.
 878             // So generally, if the adjustment is needed, the first
 879             // ConfigureNotify that we should really process is the one caused
 880             // by the adjustment operation. So we process only the first
 881             // ConfigureNotify event having the same serial that the preceeding
 882             // ReparentNotify.
 883             //
 884             // There's one exception however: we do not ignore the events for
 885             // maximized frames. The real ConfigureNotify that we would like to
 886             // act upon usually is the third one (it carries the correct
 887             // maximized bounds). However, it has the same serial (which is
 888             // obvious), and what's worse - we can't reliably determine if the
 889             // window manager/X server send us exactly two events before that,
 890             // or maybe one of them might be not sent at all - and in this case
 891             // we would need to process the second event, not the third. So we
 892             // just process everything for a maximized frame. This does produce
 893             // absolutely meaningless bounds dancing (with events sent to the
 894             // user space), but at least this is backward-compatible and quite
 895             // reliable. Should we find a way to detect and process only the
 896             // very last of ConfigureNotify events sent with the same serial,
 897             // we would like to use this approach instead of the current
 898             // processing of the very first event only.
 899             if (xe.get_serial() == reparentNotifySerial && !isMaximized())
 900             {
 901                 if (++numOfConfigureNotifyJustAfterReparentNotify > 1) {
 902                     insLog.fine("Ignored: serial matches the ReparentNotify");
 903                     return;
 904                 }
 905             }
 906         }
 907 
 908         // At this point we can calculate some reliable insets
 909         Insets insets = getNativeInsets();
 910 
 911         // Note that in some cases this kind of event may be caused by the
 912         // changed insets (like if the theme changes, or something).  However
 913         // it's difficult if at all possible to identify this situation, and
 914         // not confuse it with a regular reconfiguration w/o introducing some
 915         // serious performance degradation. So we only support changing the
 916         // insets:
 917         //    a. when a reparenting WM exits/gets replaced.
 918         //    b. when the window gets hidden/shown.
 919         //    c. if the WM is smart enough to send the PropertyNotify
 920         //       events with the updated extents.
 921 
 922         // x, y, width, height hold the coordinates of the whole frame
 923         // including the decorations.
 924         int x;
 925         int y;
 926 
 927         if (xe.get_send_event() || !isParented()) {
 928             // If the event is synthetic or we're not parented, the coordinates
 929             // are relative to the root window.
 930             x = xe.get_x() - insets.left;
 931             y = xe.get_y() - insets.top;
 932         } else {
 933             // The event is real and we're parented - the coordinates are
 934             // relative to the parent
 935             Point loc = null;
 936             if (XWM.isNoSyntheticConfigureNotifyOnLeftTopResize()) {
 937                 // there's a bug in the WM, so ask the X server
 938                 loc = queryXLocation();
 939             }
 940             if (loc == null) {
 941                 // consider the current location unchanged
 942                 // TODO: this may not be true... perhaps querying X in all cases is worthwhile?
 943                 //       after all: we already do this for Metacity which is quite common,
 944                 //       so we should not worry much about the performance.
 945                 loc = getLocation();
 946             }
 947 
 948             x = loc.x;
 949             y = loc.y;
 950         }
 951 
 952         int width = xe.get_width() + insets.left + insets.right;
 953         int height = xe.get_height() + insets.top + insets.bottom;
 954 
 955         // Now apply the new bounds
 956         WindowDimensions d = new WindowDimensions(
 957                     new Rectangle(x, y, width, height), insets, false);
 958         reportOrAdjust(d, true);
 959     }
 960 
 961     private void checkShellRectSize(Rectangle shellRect) {
 962         if (shellRect.width < 0) {
 963             shellRect.width = 1;
 964         }
 965         if (shellRect.height < 0) {
 966             shellRect.height = 1;
 967         }
 968     }
 969 
 970     private void checkShellRectPos(Rectangle shellRect) {
 971         int wm = XWM.getWMID();
 972         if (wm == XWM.MOTIF_WM || wm == XWM.CDE_WM) {
 973             if (shellRect.x == 0 && shellRect.y == 0) {
 974                 shellRect.x = shellRect.y = 1;
 975             }
 976         }
 977     }
 978 


1008     }
1009     public void setShellPosition(Rectangle rec) {
1010         if (insLog.isLoggable(Level.FINE)) insLog.fine("Setting shell position on " +
1011                                                        this + " to " + rec);
1012         XToolkit.awtLock();
1013         try {
1014             updateSizeHints(rec.x, rec.y, rec.width, rec.height);
1015             XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
1016         }
1017         finally {
1018             XToolkit.awtUnlock();
1019         }
1020     }
1021 
1022     void initResizability() {
1023         setResizable(winAttr.initialResizability);
1024     }
1025     public void setResizable(boolean resizable) {
1026         int fs = winAttr.functions;
1027         if (!isResizable() && resizable) {
1028             setNativeInsets(null);




1029             winAttr.isResizable = resizable;
1030             if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
1031                 fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
1032             } else {
1033                 fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
1034             }
1035             winAttr.functions = fs;
1036             XWM.setShellResizable(this);
1037         } else if (isResizable() && !resizable) {
1038             setNativeInsets(null);




1039             winAttr.isResizable = resizable;
1040             if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
1041                 fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
1042             } else {
1043                 fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
1044             }
1045             winAttr.functions = fs;
1046             XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false);
1047         }
1048     }
1049 
1050     Rectangle getShellBounds() {
1051         return dimensions.getClientRect();
1052     }
1053 
1054     public Rectangle getBounds() {
1055         return dimensions.getBounds();
1056     }
1057 
1058     public Dimension getSize() {


1079     public int getAbsoluteY() {
1080         // NOTE: returning this peer's location which is shell location
1081         return dimensions.getScreenBounds().y;
1082     }
1083 
1084     public int getWidth() {
1085         return getSize().width;
1086     }
1087 
1088     public int getHeight() {
1089         return getSize().height;
1090     }
1091 
1092     final public WindowDimensions getDimensions() {
1093         return dimensions;
1094     }
1095 
1096     public Point getLocationOnScreen() {
1097         XToolkit.awtLock();
1098         try {
1099             if (!areBoundsAdjusting()) {
1100                 return toGlobal(0,0);
1101             } else {
1102                 Point location = target.getLocation();
1103                 if (insLog.isLoggable(Level.FINE)) {
1104                     insLog.log(Level.FINE, "getLocationOnScreen {0} not reparented: {1} ",
1105                                new Object[] {this, location});
1106                 }
1107                 return location;
1108             }
1109         } finally {
1110             XToolkit.awtUnlock();
1111         }
1112     }
1113 
1114 
1115 /***************************************************************************************
1116  *              END            OF             I N S E T S   C O D E
1117  **************************************************************************************/
1118 
1119     protected boolean isEventDisabled(XEvent e) {
1120         switch (e.get_type()) {
1121             // Do not generate MOVED/RESIZED events since we generate them by ourselves
1122           case XConstants.ConfigureNotify:
1123               return true;
1124           case XConstants.EnterNotify:
1125           case XConstants.LeaveNotify:
1126               // Disable crossing event on outer borders of Frame so


1226     final void dumpMe() {
1227         System.err.println(">>> Peer: " + x + ", " + y + ", " + width + ", " + height);
1228     }
1229 
1230     final void dumpTarget() {
1231         int getWidth = ComponentAccessor.getWidth((Component)target);
1232         int getHeight = ComponentAccessor.getHeight((Component)target);
1233         int getTargetX = ComponentAccessor.getX((Component)target);
1234         int getTargetY = ComponentAccessor.getY((Component)target);
1235         System.err.println(">>> Target: " + getTargetX + ", " + getTargetY + ", " + getWidth + ", " + getHeight);
1236     }
1237 
1238     final void dumpShell() {
1239         dumpWindow("Shell", getShell());
1240     }
1241     final void dumpContent() {
1242         dumpWindow("Content", getContentWindow());
1243     }
1244     final void dumpParent() {
1245         long parent = XlibUtil.getParentWindow(getShell());
1246         if (parent != XConstants.None)
1247         {
1248             dumpWindow("Parent", parent);
1249         }
1250         else
1251         {
1252             System.err.println(">>> NO PARENT");
1253         }
1254     }
1255 
1256     final void dumpWindow(String id, long window) {
1257         XWindowAttributes pattr = new XWindowAttributes();
1258         try {
1259             XToolkit.awtLock();
1260             try {
1261                 int status =
1262                     XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
1263                                                      window, pattr.pData);
1264             }
1265             finally {
1266                 XToolkit.awtUnlock();


1269                                + ", " + pattr.get_y() + ", " + pattr.get_width()
1270                                + ", " + pattr.get_height());
1271         } finally {
1272             pattr.dispose();
1273         }
1274     }
1275 
1276     final void dumpAll() {
1277         dumpTarget();
1278         dumpMe();
1279         dumpParent();
1280         dumpShell();
1281         dumpContent();
1282     }
1283 
1284     boolean isMaximized() {
1285         return false;
1286     }
1287 
1288     boolean isOverrideRedirect() {

1289         return ((XToolkit)Toolkit.getDefaultToolkit()).isOverrideRedirect((Window)target);
1290     }
1291 
1292     public boolean requestWindowFocus(long time, boolean timeProvided) {
1293         focusLog.fine("Request for decorated window focus");
1294         // If this is Frame or Dialog we can't assure focus request success - but we still can try
1295         // If this is Window and its owner Frame is active we can be sure request succedded.
1296         Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
1297         Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
1298 
1299         focusLog.log(Level.FINER, "Current window is: active={0}, focused={1}",
1300                      new Object[]{ Boolean.valueOf(target == activeWindow),
1301                                    Boolean.valueOf(target == focusedWindow)});
1302 
1303         XWindowPeer toFocus = this;
1304         while (toFocus.nextTransientFor != null) {
1305             toFocus = toFocus.nextTransientFor;
1306         }
1307         if (toFocus == null || !toFocus.focusAllowedFor()) {
1308             // This might change when WM will have property to determine focus policy.