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

Print this page




  61     }
  62 
  63     public long getShell() {
  64         return window;
  65     }
  66 
  67     public long getContentWindow() {
  68         return (content == null) ? window : content.getWindow();
  69     }
  70 
  71     void preInit(XCreateWindowParams params) {
  72         super.preInit(params);
  73         winAttr.initialFocus = true;
  74 
  75         currentInsets = new Insets(0,0,0,0);
  76         applyGuessedInsets();
  77 
  78         Rectangle bounds = (Rectangle)params.get(BOUNDS);
  79         dimensions = new WindowDimensions(bounds, getRealInsets(), false);
  80         params.put(BOUNDS, dimensions.getClientRect());
  81         if (insLog.isLoggable(PlatformLogger.FINE)) {
  82             insLog.fine("Initial dimensions {0}", dimensions);
  83         }
  84 
  85         // Deny default processing of these events on the shell - proxy will take care of
  86         // them instead
  87         Long eventMask = (Long)params.get(EVENT_MASK);
  88         params.add(EVENT_MASK, Long.valueOf(eventMask.longValue() & ~(XConstants.FocusChangeMask | XConstants.KeyPressMask | XConstants.KeyReleaseMask)));
  89     }
  90 
  91     void postInit(XCreateWindowParams params) {
  92         // The size hints must be set BEFORE mapping the window (see 6895647)
  93         updateSizeHints(dimensions);
  94 
  95         // The super method maps the window if it's visible on the shared level
  96         super.postInit(params);
  97 
  98         // The lines that follow need to be in a postInit, so they
  99         // happen after the X window is created.
 100         initResizability();
 101         XWM.requestWMExtents(getWindow());


 164     XFocusProxyWindow createFocusProxy() {
 165         return new XFocusProxyWindow(this);
 166     }
 167 
 168     protected XAtomList getWMProtocols() {
 169         XAtomList protocols = super.getWMProtocols();
 170         protocols.add(wm_delete_window);
 171         protocols.add(wm_take_focus);
 172         return protocols;
 173     }
 174 
 175     public Graphics getGraphics() {
 176         AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor();
 177         return getGraphics(content.surfaceData,
 178                            compAccessor.getForeground(target),
 179                            compAccessor.getBackground(target),
 180                            compAccessor.getFont(target));
 181     }
 182 
 183     public void setTitle(String title) {
 184         if (log.isLoggable(PlatformLogger.FINE)) {
 185             log.fine("Title is " + title);
 186         }
 187         winAttr.title = title;
 188         updateWMName();
 189     }
 190 
 191     protected String getWMName() {
 192         if (winAttr.title == null || winAttr.title.trim().equals("")) {
 193             return " ";
 194         } else {
 195             return winAttr.title;
 196         }
 197     }
 198 
 199     void updateWMName() {
 200         super.updateWMName();
 201         String name = getWMName();
 202         XToolkit.awtLock();
 203         try {
 204             if (name == null || name.trim().equals("")) {


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


 258     }
 259 
 260     // insets which we get from WM (e.g from _NET_FRAME_EXTENTS)
 261     private Insets wm_set_insets;
 262 
 263     private Insets getWMSetInsets(XAtom changedAtom) {
 264         if (isEmbedded()) {
 265             return null;
 266         }
 267 
 268         if (wm_set_insets != null) {
 269             return wm_set_insets;
 270         }
 271 
 272         if (changedAtom == null) {
 273             wm_set_insets = XWM.getInsetsFromExtents(getWindow());
 274         } else {
 275             wm_set_insets = XWM.getInsetsFromProp(getWindow(), changedAtom);
 276         }
 277 
 278         if (insLog.isLoggable(PlatformLogger.FINER)) {
 279             insLog.finer("FRAME_EXTENTS: {0}", wm_set_insets);
 280         }
 281 
 282         if (wm_set_insets != null) {
 283             wm_set_insets = copy(wm_set_insets);
 284         }
 285         return wm_set_insets;
 286     }
 287 
 288     private void resetWMSetInsets() {
 289         wm_set_insets = null;
 290     }
 291 
 292     public void handlePropertyNotify(XEvent xev) {
 293         super.handlePropertyNotify(xev);
 294 
 295         XPropertyEvent ev = xev.get_xproperty();
 296         if (ev.get_atom() == XWM.XA_KDE_NET_WM_FRAME_STRUT.getAtom()
 297             || ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom())
 298         {
 299             getWMSetInsets(XAtom.get(ev.get_atom()));
 300         }
 301     }
 302 
 303     long reparent_serial = 0;
 304 
 305     public void handleReparentNotifyEvent(XEvent xev) {
 306         XReparentEvent  xe = xev.get_xreparent();
 307         if (insLog.isLoggable(PlatformLogger.FINE)) {
 308             insLog.fine(xe.toString());
 309         }
 310         reparent_serial = xe.get_serial();
 311         XToolkit.awtLock();
 312         try {
 313             long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
 314 
 315             if (isEmbedded()) {
 316                 setReparented(true);
 317                 insets_corrected = true;
 318                 return;
 319             }
 320             Component t = (Component)target;
 321             if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
 322                 setReparented(true);
 323                 insets_corrected = true;
 324                 reshape(dimensions, SET_SIZE, false);
 325             } else if (xe.get_parent() == root) {
 326                 configure_seen = false;
 327                 insets_corrected = false;
 328 
 329                 /*
 330                  * We can be repareted to root for two reasons:
 331                  *   . setVisible(false)
 332                  *   . WM exited
 333                  */
 334                 if (isVisible()) { /* WM exited */
 335                     /* Work around 4775545 */
 336                     XWM.getWM().unshadeKludge(this);
 337                     insLog.fine("- WM exited");
 338                 } else {
 339                     insLog.fine(" - reparent due to hide");
 340                 }
 341             } else { /* reparented to WM frame, figure out our insets */
 342                 setReparented(true);
 343                 insets_corrected = false;
 344 
 345                 // Check if we have insets provided by the WM
 346                 Insets correctWM = getWMSetInsets(null);
 347                 if (correctWM != null) {
 348                     if (insLog.isLoggable(PlatformLogger.FINER)) {
 349                         insLog.finer("wm-provided insets {0}", correctWM);
 350                     }
 351                     // If these insets are equal to our current insets - no actions are necessary
 352                     Insets dimInsets = dimensions.getInsets();
 353                     if (correctWM.equals(dimInsets)) {
 354                         insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
 355                         no_reparent_artifacts = true;
 356                         insets_corrected = true;
 357                         applyGuessedInsets();
 358                         return;
 359                     }
 360                 } else {
 361                     correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
 362 
 363                     if (insLog.isLoggable(PlatformLogger.FINER)) {
 364                         if (correctWM != null) {
 365                             insLog.finer("correctWM {0}", correctWM);
 366                         } else {
 367                             insLog.finer("correctWM insets are not available, waiting for configureNotify");
 368                         }
 369                     }
 370                 }
 371 
 372                 if (correctWM != null) {
 373                     handleCorrectInsets(correctWM);
 374                 }
 375             }
 376         } finally {
 377             XToolkit.awtUnlock();
 378         }
 379     }
 380 
 381     protected void handleCorrectInsets(Insets correctWM) {
 382         XToolkit.awtLock();
 383         try {
 384             /*
 385              * Ok, now see if we need adjust window size because
 386              * initial insets were wrong (most likely they were).
 387              */
 388             Insets correction = difference(correctWM, currentInsets);
 389             if (insLog.isLoggable(PlatformLogger.FINEST)) {
 390                 insLog.finest("Corrention {0}", correction);
 391             }
 392             if (!isNull(correction)) {
 393                 currentInsets = copy(correctWM);
 394                 applyGuessedInsets();
 395 
 396                 //Fix for 6318109: PIT: Min Size is not honored properly when a
 397                 //smaller size is specified in setSize(), XToolkit
 398                 //update minimum size hints
 399                 updateMinSizeHints();
 400             }
 401             if (insLog.isLoggable(PlatformLogger.FINER)) {
 402                 insLog.finer("Dimensions before reparent: " + dimensions);
 403             }
 404 
 405             dimensions.setInsets(getRealInsets());
 406             insets_corrected = true;
 407 
 408             if (isMaximized()) {
 409                 return;
 410             }
 411 
 412             /*
 413              * If this window has been sized by a pack() we need
 414              * to keep the interior geometry intact.  Since pack()
 415              * computed width and height with wrong insets, we
 416              * must adjust the target dimensions appropriately.
 417              */
 418             if ((getHints().get_flags() & (XUtilConstants.USPosition | XUtilConstants.PPosition)) != 0) {
 419                 reshape(dimensions, SET_BOUNDS, false);
 420             } else {
 421                 reshape(dimensions, SET_SIZE, false);


 456 
 457     public void revalidate() {
 458         XToolkit.executeOnEventHandlerThread(target, new Runnable() {
 459                 public void run() {
 460                     target.invalidate();
 461                     target.validate();
 462                 }
 463             });
 464     }
 465 
 466     Insets getRealInsets() {
 467         if (isNull(currentInsets)) {
 468             applyGuessedInsets();
 469         }
 470         return currentInsets;
 471     }
 472 
 473     public Insets getInsets() {
 474         Insets in = copy(getRealInsets());
 475         in.top += getMenuBarHeight();
 476         if (insLog.isLoggable(PlatformLogger.FINEST)) {
 477             insLog.finest("Get insets returns {0}", in);
 478         }
 479         return in;
 480     }
 481 
 482     boolean gravityBug() {
 483         return XWM.configureGravityBuggy();
 484     }
 485 
 486     // The height of area used to display current active input method
 487     int getInputMethodHeight() {
 488         return 0;
 489     }
 490 
 491     void updateSizeHints(WindowDimensions dims) {
 492         Rectangle rec = dims.getClientRect();
 493         checkShellRect(rec);
 494         updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 495     }
 496 
 497     void updateSizeHints() {
 498         updateSizeHints(dimensions);
 499     }
 500 
 501     // Coordinates are that of the target
 502     // Called only on Toolkit thread
 503     public void reshape(WindowDimensions newDimensions, int op,
 504                         boolean userReshape)
 505     {
 506         if (insLog.isLoggable(PlatformLogger.FINE)) {
 507             insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
 508         }
 509         if (userReshape) {
 510             // We handle only userReshape == true cases. It means that
 511             // if the window manager or any other part of the windowing
 512             // system sets inappropriate size for this window, we can
 513             // do nothing but accept it.
 514             Rectangle newBounds = newDimensions.getBounds();
 515             Insets insets = newDimensions.getInsets();
 516             // Inherit isClientSizeSet from newDimensions
 517             if (newDimensions.isClientSizeSet()) {
 518                 newBounds = new Rectangle(newBounds.x, newBounds.y,
 519                                           newBounds.width - insets.left - insets.right,
 520                                           newBounds.height - insets.top - insets.bottom);
 521             }
 522             newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet());
 523         }
 524         XToolkit.awtLock();
 525         try {
 526             if (!isReparented() || !isVisible()) {
 527                 if (insLog.isLoggable(PlatformLogger.FINE)) {
 528                     insLog.fine("- not reparented({0}) or not visible({1}), default reshape",
 529                            Boolean.valueOf(isReparented()), Boolean.valueOf(visible));
 530                 }
 531 
 532                 // Fix for 6323293.
 533                 // This actually is needed to preserve compatibility with previous releases -
 534                 // some of licensees are expecting componentMoved event on invisible one while
 535                 // its location changes.
 536                 Point oldLocation = getLocation();
 537 
 538                 Point newLocation = new Point(AWTAccessor.getComponentAccessor().getX((Component)target),
 539                                               AWTAccessor.getComponentAccessor().getY((Component)target));
 540 
 541                 if (!newLocation.equals(oldLocation)) {
 542                     handleMoved(newDimensions);
 543                 }
 544 
 545                 dimensions = new WindowDimensions(newDimensions);
 546                 updateSizeHints(dimensions);
 547                 Rectangle client = dimensions.getClientRect();


 615               break;
 616           case SET_SIZE:
 617               // Set size sets bounds size. However, until the window is mapped we
 618               // should use client coordinates
 619               dims.setSize(width, height);
 620               break;
 621           case SET_CLIENT_SIZE: {
 622               // Sets client rect size. Width and height contain insets.
 623               Insets in = currentInsets;
 624               width -= in.left+in.right;
 625               height -= in.top+in.bottom;
 626               dims.setClientSize(width, height);
 627               break;
 628           }
 629           case SET_BOUNDS:
 630           default:
 631               dims.setLocation(x, y);
 632               dims.setSize(width, height);
 633               break;
 634         }
 635         if (insLog.isLoggable(PlatformLogger.FINE)) {
 636             insLog.fine("For the operation {0} new dimensions are {1}",
 637                         operationToString(operation), dims);
 638         }
 639 
 640         reshape(dims, operation, userReshape);
 641     }
 642 
 643     // This method gets overriden in XFramePeer & XDialogPeer.
 644     abstract boolean isTargetUndecorated();
 645 
 646     /**
 647      * @see java.awt.peer.ComponentPeer#setBounds
 648      */
 649     public void setBounds(int x, int y, int width, int height, int op) {
 650         // TODO: Rewrite with WindowDimensions
 651         reshape(x, y, width, height, op, true);
 652         validateSurface();
 653     }
 654 
 655     // Coordinates are that of the shell
 656     void reconfigureContentWindow(WindowDimensions dims) {
 657         if (content == null) {
 658             insLog.fine("WARNING: Content window is null");
 659             return;
 660         }
 661         content.setContentBounds(dims);
 662     }
 663 
 664     boolean no_reparent_artifacts = false;
 665     public void handleConfigureNotifyEvent(XEvent xev) {
 666         assert (SunToolkit.isAWTLockHeldByCurrentThread());
 667         XConfigureEvent xe = xev.get_xconfigure();
 668         if (insLog.isLoggable(PlatformLogger.FINE)) {
 669             insLog.fine("Configure notify {0}", xe);
 670         }
 671 
 672         // XXX: should really only consider synthetic events, but
 673         if (isReparented()) {
 674             configure_seen = true;
 675         }
 676 
 677         if (!isMaximized()
 678             && (xe.get_serial() == reparent_serial || xe.get_window() != getShell())
 679             && !no_reparent_artifacts)
 680         {
 681             insLog.fine("- reparent artifact, skipping");
 682             return;
 683         }
 684         no_reparent_artifacts = false;
 685 
 686         /**
 687          * When there is a WM we receive some CN before being visible and after.
 688          * We should skip all CN which are before being visible, because we assume
 689          * the gravity is in action while it is not yet.
 690          *
 691          * When there is no WM we receive CN only _before_ being visible.
 692          * We should process these CNs.
 693          */
 694         if (!isVisible() && XWM.getWMID() != XWM.NO_WM) {
 695             insLog.fine(" - not visible, skipping");
 696             return;
 697         }
 698 
 699         /*
 700          * Some window managers configure before we are reparented and
 701          * the send event flag is set! ugh... (Enlighetenment for one,
 702          * possibly MWM as well).  If we haven't been reparented yet
 703          * this is just the WM shuffling us into position.  Ignore
 704          * it!!!! or we wind up in a bogus location.
 705          */
 706         int runningWM = XWM.getWMID();
 707         if (insLog.isLoggable(PlatformLogger.FINE)) {
 708             insLog.fine("reparented={0}, visible={1}, WM={2}, decorations={3}",
 709                         isReparented(), isVisible(), runningWM, getDecorations());
 710         }
 711         if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
 712                 &&  !XWM.isNonReparentingWM()
 713                 && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
 714             insLog.fine("- visible but not reparented, skipping");
 715             return;
 716         }
 717         //Last chance to correct insets
 718         if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
 719             long parent = XlibUtil.getParentWindow(window);
 720             Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
 721             if (insLog.isLoggable(PlatformLogger.FINER)) {
 722                 if (correctWM != null) {
 723                     insLog.finer("Configure notify - insets : " + correctWM);
 724                 } else {
 725                     insLog.finer("Configure notify - insets are still not available");
 726                 }
 727             }
 728             if (correctWM != null) {
 729                 handleCorrectInsets(correctWM);
 730             } else {
 731                 //Only one attempt to correct insets is made (to lower risk)
 732                 //if insets are still not available we simply set the flag
 733                 insets_corrected = true;
 734             }
 735         }
 736 
 737         updateChildrenSizes();
 738 
 739         // Bounds of the window
 740         Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds((Component)target);
 741 
 742         Point newLocation = targetBounds.getLocation();
 743         if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
 744             // Location, Client size + insets
 745             newLocation = new Point(xe.get_x() - currentInsets.left, xe.get_y() - currentInsets.top);
 746         } else {
 747             // ICCCM 4.1.5 states that a real ConfigureNotify will be sent when
 748             // a window is resized but the client can not tell if the window was
 749             // moved or not. The client should consider the position as unkown
 750             // and use TranslateCoordinates to find the actual position.
 751             //
 752             // TODO this should be the default for every case.
 753             switch (XWM.getWMID()) {
 754                 case XWM.CDE_WM:
 755                 case XWM.MOTIF_WM:
 756                 case XWM.METACITY_WM:
 757                 case XWM.MUTTER_WM:
 758                 case XWM.SAWFISH_WM:
 759                 {
 760                     Point xlocation = queryXLocation();
 761                     if (log.isLoggable(PlatformLogger.FINE)) {
 762                         log.fine("New X location: {0}", xlocation);
 763                     }
 764                     if (xlocation != null) {
 765                         newLocation = xlocation;
 766                     }
 767                     break;
 768                 }
 769                 default:
 770                     break;
 771             }
 772         }
 773 
 774         WindowDimensions newDimensions =
 775                 new WindowDimensions(newLocation,
 776                 new Dimension(xe.get_width(), xe.get_height()),
 777                 copy(currentInsets),
 778                 true);
 779 
 780         if (insLog.isLoggable(PlatformLogger.FINER)) {
 781             insLog.finer("Insets are {0}, new dimensions {1}",
 782                      currentInsets, newDimensions);
 783         }
 784 
 785         checkIfOnNewScreen(newDimensions.getBounds());
 786 
 787         Point oldLocation = getLocation();
 788         dimensions = newDimensions;
 789         if (!newLocation.equals(oldLocation)) {
 790             handleMoved(newDimensions);
 791         }
 792         reconfigureContentWindow(newDimensions);
 793         updateChildrenSizes();
 794 
 795         repositionSecurityWarning();
 796     }
 797 
 798     private void checkShellRectSize(Rectangle shellRect) {
 799         shellRect.width = Math.max(MIN_SIZE, shellRect.width);
 800         shellRect.height = Math.max(MIN_SIZE, shellRect.height);
 801     }
 802 
 803     private void checkShellRectPos(Rectangle shellRect) {
 804         int wm = XWM.getWMID();
 805         if (wm == XWM.MOTIF_WM || wm == XWM.CDE_WM) {
 806             if (shellRect.x == 0 && shellRect.y == 0) {
 807                 shellRect.x = shellRect.y = 1;
 808             }
 809         }
 810     }
 811 
 812     private void checkShellRect(Rectangle shellRect) {
 813         checkShellRectSize(shellRect);
 814         checkShellRectPos(shellRect);
 815     }
 816 
 817     public void setShellBounds(Rectangle rec) {
 818         if (insLog.isLoggable(PlatformLogger.FINE)) {
 819             insLog.fine("Setting shell bounds on " + this + " to " + rec);
 820         }
 821         XToolkit.awtLock();
 822         try {
 823             updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 824             XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
 825             XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
 826         }
 827         finally {
 828             XToolkit.awtUnlock();
 829         }
 830     }
 831     public void setShellSize(Rectangle rec) {
 832         if (insLog.isLoggable(PlatformLogger.FINE)) {
 833             insLog.fine("Setting shell size on " + this + " to " + rec);
 834         }
 835         XToolkit.awtLock();
 836         try {
 837             updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 838             XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
 839         }
 840         finally {
 841             XToolkit.awtUnlock();
 842         }
 843     }
 844     public void setShellPosition(Rectangle rec) {
 845         if (insLog.isLoggable(PlatformLogger.FINE)) {
 846             insLog.fine("Setting shell position on " + this + " to " + rec);
 847         }
 848         XToolkit.awtLock();
 849         try {
 850             updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 851             XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
 852         }
 853         finally {
 854             XToolkit.awtUnlock();
 855         }
 856     }
 857 
 858     void initResizability() {
 859         setResizable(winAttr.initialResizability);
 860     }
 861     public void setResizable(boolean resizable) {
 862         int fs = winAttr.functions;
 863         if (!isResizable() && resizable) {
 864             currentInsets = new Insets(0, 0, 0, 0);
 865             resetWMSetInsets();


 927 
 928     public int getWidth() {
 929         return getSize().width;
 930     }
 931 
 932     public int getHeight() {
 933         return getSize().height;
 934     }
 935 
 936     final public WindowDimensions getDimensions() {
 937         return dimensions;
 938     }
 939 
 940     public Point getLocationOnScreen() {
 941         XToolkit.awtLock();
 942         try {
 943             if (configure_seen) {
 944                 return toGlobal(0,0);
 945             } else {
 946                 Point location = target.getLocation();
 947                 if (insLog.isLoggable(PlatformLogger.FINE)) {
 948                     insLog.fine("getLocationOnScreen {0} not reparented: {1} ",
 949                                 this, location);
 950                 }
 951                 return location;
 952             }
 953         } finally {
 954             XToolkit.awtUnlock();
 955         }
 956     }
 957 
 958 
 959 /***************************************************************************************
 960  *              END            OF             I N S E T S   C O D E
 961  **************************************************************************************/
 962 
 963     protected boolean isEventDisabled(XEvent e) {
 964         switch (e.get_type()) {
 965             // Do not generate MOVED/RESIZED events since we generate them by ourselves
 966           case XConstants.ConfigureNotify:
 967               return true;
 968           case XConstants.EnterNotify:
 969           case XConstants.LeaveNotify:
 970               // Disable crossing event on outer borders of Frame so
 971               // we receive only one set of cross notifications(first set is from content window)
 972               return true;
 973           default:
 974               return super.isEventDisabled(e);
 975         }
 976     }
 977 
 978     int getDecorations() {
 979         return winAttr.decorations;
 980     }
 981 
 982     int getFunctions() {
 983         return winAttr.functions;
 984     }
 985 
 986     public void setVisible(boolean vis) {
 987         if (log.isLoggable(PlatformLogger.FINER)) {
 988             log.finer("Setting {0} to visible {1}", this, Boolean.valueOf(vis));
 989         }
 990         if (vis && !isVisible()) {
 991             XWM.setShellDecor(this);
 992             super.setVisible(vis);
 993             if (winAttr.isResizable) {
 994                 //Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.
 995                 //We need to update frame's minimum size, not to reset it
 996                 XWM.removeSizeHints(this, XUtilConstants.PMaxSize);
 997                 updateMinimumSize();
 998             }
 999         } else {
1000             super.setVisible(vis);
1001         }
1002     }
1003 
1004     protected void suppressWmTakeFocus(boolean doSuppress) {
1005         XAtomList protocols = getWMProtocols();
1006         if (doSuppress) {
1007             protocols.remove(wm_take_focus);


1020         if (iconWindow != null) {
1021             iconWindow.destroy();
1022         }
1023 
1024         super.dispose();
1025     }
1026 
1027     public void handleClientMessage(XEvent xev) {
1028         super.handleClientMessage(xev);
1029         XClientMessageEvent cl = xev.get_xclient();
1030         if ((wm_protocols != null) && (cl.get_message_type() == wm_protocols.getAtom())) {
1031             if (cl.get_data(0) == wm_delete_window.getAtom()) {
1032                 handleQuit();
1033             } else if (cl.get_data(0) == wm_take_focus.getAtom()) {
1034                 handleWmTakeFocus(cl);
1035             }
1036         }
1037     }
1038 
1039     private void handleWmTakeFocus(XClientMessageEvent cl) {
1040         if (focusLog.isLoggable(PlatformLogger.FINE)) {
1041             focusLog.fine("WM_TAKE_FOCUS on {0}", this);
1042         }
1043         requestWindowFocus(cl.get_data(1), true);
1044     }
1045 
1046     /**
1047      * Requests focus to this decorated top-level by requesting X input focus
1048      * to the shell window.
1049      */
1050     protected void requestXFocus(long time, boolean timeProvided) {
1051         // We have proxied focus mechanism - instead of shell the focus is held
1052         // by "proxy" - invisible mapped window. When we want to set X input focus to
1053         // toplevel set it on proxy instead.
1054         if (focusProxy == null) {
1055             if (focusLog.isLoggable(PlatformLogger.WARNING)) {
1056                 focusLog.warning("Focus proxy is null for " + this);
1057             }
1058         } else {
1059             if (focusLog.isLoggable(PlatformLogger.FINE)) {
1060                 focusLog.fine("Requesting focus to proxy: " + focusProxy);
1061             }
1062             if (timeProvided) {
1063                 focusProxy.xRequestFocus(time);
1064             } else {
1065                 focusProxy.xRequestFocus();
1066             }
1067         }
1068     }
1069 
1070     XFocusProxyWindow getFocusProxy() {
1071         return focusProxy;
1072     }
1073 
1074     public void handleQuit() {
1075         postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_CLOSING));
1076     }
1077 
1078     final void dumpMe() {
1079         System.err.println(">>> Peer: " + x + ", " + y + ", " + width + ", " + height);


1133         dumpShell();
1134         dumpContent();
1135     }
1136 
1137     boolean isMaximized() {
1138         return false;
1139     }
1140 
1141     @Override
1142     boolean isOverrideRedirect() {
1143         return Window.Type.POPUP.equals(getWindowType());
1144     }
1145 
1146     public boolean requestWindowFocus(long time, boolean timeProvided) {
1147         focusLog.fine("Request for decorated window focus");
1148         // If this is Frame or Dialog we can't assure focus request success - but we still can try
1149         // If this is Window and its owner Frame is active we can be sure request succedded.
1150         Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
1151         Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
1152 
1153         if (focusLog.isLoggable(PlatformLogger.FINER)) {
1154             focusLog.finer("Current window is: active={0}, focused={1}",
1155                        Boolean.valueOf(target == activeWindow),
1156                        Boolean.valueOf(target == focusedWindow));
1157         }
1158 
1159         XWindowPeer toFocus = this;
1160         while (toFocus.nextTransientFor != null) {
1161             toFocus = toFocus.nextTransientFor;
1162         }
1163         if (toFocus == null || !toFocus.focusAllowedFor()) {
1164             // This might change when WM will have property to determine focus policy.
1165             // Right now, because policy is unknown we can't be sure we succedded
1166             return false;
1167         }
1168         if (this == toFocus) {
1169             if (isWMStateNetHidden()) {
1170                 focusLog.fine("The window is unmapped, so rejecting the request");
1171                 return false;
1172             }
1173             if (target == activeWindow && target != focusedWindow) {
1174                 // Happens when an owned window is currently focused
1175                 focusLog.fine("Focus is on child window - transfering it back to the owner");
1176                 handleWindowFocusInSync(-1);
1177                 return true;
1178             }
1179             Window realNativeFocusedWindow = XWindowPeer.getNativeFocusedWindow();
1180             if (focusLog.isLoggable(PlatformLogger.FINEST)) {
1181                 focusLog.finest("Real native focused window: " + realNativeFocusedWindow +
1182                             "\nKFM's focused window: " + focusedWindow);
1183             }
1184 
1185             // A workaround for Metacity. See 6522725, 6613426, 7147075.
1186             if (target == realNativeFocusedWindow && XWM.getWMID() == XWM.METACITY_WM) {
1187                 if (focusLog.isLoggable(PlatformLogger.FINE)) {
1188                     focusLog.fine("The window is already natively focused.");
1189                 }
1190                 return true;
1191             }
1192         }
1193         if (focusLog.isLoggable(PlatformLogger.FINE)) {
1194             focusLog.fine("Requesting focus to " + (this == toFocus ? "this window" : toFocus));
1195         }
1196 
1197         if (timeProvided) {
1198             toFocus.requestXFocus(time);
1199         } else {
1200             toFocus.requestXFocus();
1201         }
1202         return (this == toFocus);
1203     }
1204 
1205     XWindowPeer actualFocusedWindow = null;
1206     void setActualFocusedWindow(XWindowPeer actualFocusedWindow) {
1207         synchronized(getStateLock()) {
1208             this.actualFocusedWindow = actualFocusedWindow;
1209         }
1210     }
1211 
1212     boolean requestWindowFocus(XWindowPeer actualFocusedWindow,
1213                                long time, boolean timeProvided)




  61     }
  62 
  63     public long getShell() {
  64         return window;
  65     }
  66 
  67     public long getContentWindow() {
  68         return (content == null) ? window : content.getWindow();
  69     }
  70 
  71     void preInit(XCreateWindowParams params) {
  72         super.preInit(params);
  73         winAttr.initialFocus = true;
  74 
  75         currentInsets = new Insets(0,0,0,0);
  76         applyGuessedInsets();
  77 
  78         Rectangle bounds = (Rectangle)params.get(BOUNDS);
  79         dimensions = new WindowDimensions(bounds, getRealInsets(), false);
  80         params.put(BOUNDS, dimensions.getClientRect());
  81         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
  82             insLog.fine("Initial dimensions {0}", dimensions);
  83         }
  84 
  85         // Deny default processing of these events on the shell - proxy will take care of
  86         // them instead
  87         Long eventMask = (Long)params.get(EVENT_MASK);
  88         params.add(EVENT_MASK, Long.valueOf(eventMask.longValue() & ~(XConstants.FocusChangeMask | XConstants.KeyPressMask | XConstants.KeyReleaseMask)));
  89     }
  90 
  91     void postInit(XCreateWindowParams params) {
  92         // The size hints must be set BEFORE mapping the window (see 6895647)
  93         updateSizeHints(dimensions);
  94 
  95         // The super method maps the window if it's visible on the shared level
  96         super.postInit(params);
  97 
  98         // The lines that follow need to be in a postInit, so they
  99         // happen after the X window is created.
 100         initResizability();
 101         XWM.requestWMExtents(getWindow());


 164     XFocusProxyWindow createFocusProxy() {
 165         return new XFocusProxyWindow(this);
 166     }
 167 
 168     protected XAtomList getWMProtocols() {
 169         XAtomList protocols = super.getWMProtocols();
 170         protocols.add(wm_delete_window);
 171         protocols.add(wm_take_focus);
 172         return protocols;
 173     }
 174 
 175     public Graphics getGraphics() {
 176         AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor();
 177         return getGraphics(content.surfaceData,
 178                            compAccessor.getForeground(target),
 179                            compAccessor.getBackground(target),
 180                            compAccessor.getFont(target));
 181     }
 182 
 183     public void setTitle(String title) {
 184         if (log.isLoggable(PlatformLogger.Level.FINE)) {
 185             log.fine("Title is " + title);
 186         }
 187         winAttr.title = title;
 188         updateWMName();
 189     }
 190 
 191     protected String getWMName() {
 192         if (winAttr.title == null || winAttr.title.trim().equals("")) {
 193             return " ";
 194         } else {
 195             return winAttr.title;
 196         }
 197     }
 198 
 199     void updateWMName() {
 200         super.updateWMName();
 201         String name = getWMName();
 202         XToolkit.awtLock();
 203         try {
 204             if (name == null || name.trim().equals("")) {


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


 258     }
 259 
 260     // insets which we get from WM (e.g from _NET_FRAME_EXTENTS)
 261     private Insets wm_set_insets;
 262 
 263     private Insets getWMSetInsets(XAtom changedAtom) {
 264         if (isEmbedded()) {
 265             return null;
 266         }
 267 
 268         if (wm_set_insets != null) {
 269             return wm_set_insets;
 270         }
 271 
 272         if (changedAtom == null) {
 273             wm_set_insets = XWM.getInsetsFromExtents(getWindow());
 274         } else {
 275             wm_set_insets = XWM.getInsetsFromProp(getWindow(), changedAtom);
 276         }
 277 
 278         if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
 279             insLog.finer("FRAME_EXTENTS: {0}", wm_set_insets);
 280         }
 281 
 282         if (wm_set_insets != null) {
 283             wm_set_insets = copy(wm_set_insets);
 284         }
 285         return wm_set_insets;
 286     }
 287 
 288     private void resetWMSetInsets() {
 289         wm_set_insets = null;
 290     }
 291 
 292     public void handlePropertyNotify(XEvent xev) {
 293         super.handlePropertyNotify(xev);
 294 
 295         XPropertyEvent ev = xev.get_xproperty();
 296         if (ev.get_atom() == XWM.XA_KDE_NET_WM_FRAME_STRUT.getAtom()
 297             || ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom())
 298         {
 299             getWMSetInsets(XAtom.get(ev.get_atom()));
 300         }
 301     }
 302 
 303     long reparent_serial = 0;
 304 
 305     public void handleReparentNotifyEvent(XEvent xev) {
 306         XReparentEvent  xe = xev.get_xreparent();
 307         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 308             insLog.fine(xe.toString());
 309         }
 310         reparent_serial = xe.get_serial();
 311         XToolkit.awtLock();
 312         try {
 313             long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
 314 
 315             if (isEmbedded()) {
 316                 setReparented(true);
 317                 insets_corrected = true;
 318                 return;
 319             }
 320             Component t = (Component)target;
 321             if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
 322                 setReparented(true);
 323                 insets_corrected = true;
 324                 reshape(dimensions, SET_SIZE, false);
 325             } else if (xe.get_parent() == root) {
 326                 configure_seen = false;
 327                 insets_corrected = false;
 328 
 329                 /*
 330                  * We can be repareted to root for two reasons:
 331                  *   . setVisible(false)
 332                  *   . WM exited
 333                  */
 334                 if (isVisible()) { /* WM exited */
 335                     /* Work around 4775545 */
 336                     XWM.getWM().unshadeKludge(this);
 337                     insLog.fine("- WM exited");
 338                 } else {
 339                     insLog.fine(" - reparent due to hide");
 340                 }
 341             } else { /* reparented to WM frame, figure out our insets */
 342                 setReparented(true);
 343                 insets_corrected = false;
 344 
 345                 // Check if we have insets provided by the WM
 346                 Insets correctWM = getWMSetInsets(null);
 347                 if (correctWM != null) {
 348                     if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
 349                         insLog.finer("wm-provided insets {0}", correctWM);
 350                     }
 351                     // If these insets are equal to our current insets - no actions are necessary
 352                     Insets dimInsets = dimensions.getInsets();
 353                     if (correctWM.equals(dimInsets)) {
 354                         insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
 355                         no_reparent_artifacts = true;
 356                         insets_corrected = true;
 357                         applyGuessedInsets();
 358                         return;
 359                     }
 360                 } else {
 361                     correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
 362 
 363                     if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
 364                         if (correctWM != null) {
 365                             insLog.finer("correctWM {0}", correctWM);
 366                         } else {
 367                             insLog.finer("correctWM insets are not available, waiting for configureNotify");
 368                         }
 369                     }
 370                 }
 371 
 372                 if (correctWM != null) {
 373                     handleCorrectInsets(correctWM);
 374                 }
 375             }
 376         } finally {
 377             XToolkit.awtUnlock();
 378         }
 379     }
 380 
 381     protected void handleCorrectInsets(Insets correctWM) {
 382         XToolkit.awtLock();
 383         try {
 384             /*
 385              * Ok, now see if we need adjust window size because
 386              * initial insets were wrong (most likely they were).
 387              */
 388             Insets correction = difference(correctWM, currentInsets);
 389             if (insLog.isLoggable(PlatformLogger.Level.FINEST)) {
 390                 insLog.finest("Corrention {0}", correction);
 391             }
 392             if (!isNull(correction)) {
 393                 currentInsets = copy(correctWM);
 394                 applyGuessedInsets();
 395 
 396                 //Fix for 6318109: PIT: Min Size is not honored properly when a
 397                 //smaller size is specified in setSize(), XToolkit
 398                 //update minimum size hints
 399                 updateMinSizeHints();
 400             }
 401             if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
 402                 insLog.finer("Dimensions before reparent: " + dimensions);
 403             }
 404 
 405             dimensions.setInsets(getRealInsets());
 406             insets_corrected = true;
 407 
 408             if (isMaximized()) {
 409                 return;
 410             }
 411 
 412             /*
 413              * If this window has been sized by a pack() we need
 414              * to keep the interior geometry intact.  Since pack()
 415              * computed width and height with wrong insets, we
 416              * must adjust the target dimensions appropriately.
 417              */
 418             if ((getHints().get_flags() & (XUtilConstants.USPosition | XUtilConstants.PPosition)) != 0) {
 419                 reshape(dimensions, SET_BOUNDS, false);
 420             } else {
 421                 reshape(dimensions, SET_SIZE, false);


 456 
 457     public void revalidate() {
 458         XToolkit.executeOnEventHandlerThread(target, new Runnable() {
 459                 public void run() {
 460                     target.invalidate();
 461                     target.validate();
 462                 }
 463             });
 464     }
 465 
 466     Insets getRealInsets() {
 467         if (isNull(currentInsets)) {
 468             applyGuessedInsets();
 469         }
 470         return currentInsets;
 471     }
 472 
 473     public Insets getInsets() {
 474         Insets in = copy(getRealInsets());
 475         in.top += getMenuBarHeight();
 476         if (insLog.isLoggable(PlatformLogger.Level.FINEST)) {
 477             insLog.finest("Get insets returns {0}", in);
 478         }
 479         return in;
 480     }
 481 
 482     boolean gravityBug() {
 483         return XWM.configureGravityBuggy();
 484     }
 485 
 486     // The height of area used to display current active input method
 487     int getInputMethodHeight() {
 488         return 0;
 489     }
 490 
 491     void updateSizeHints(WindowDimensions dims) {
 492         Rectangle rec = dims.getClientRect();
 493         checkShellRect(rec);
 494         updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 495     }
 496 
 497     void updateSizeHints() {
 498         updateSizeHints(dimensions);
 499     }
 500 
 501     // Coordinates are that of the target
 502     // Called only on Toolkit thread
 503     public void reshape(WindowDimensions newDimensions, int op,
 504                         boolean userReshape)
 505     {
 506         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 507             insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
 508         }
 509         if (userReshape) {
 510             // We handle only userReshape == true cases. It means that
 511             // if the window manager or any other part of the windowing
 512             // system sets inappropriate size for this window, we can
 513             // do nothing but accept it.
 514             Rectangle newBounds = newDimensions.getBounds();
 515             Insets insets = newDimensions.getInsets();
 516             // Inherit isClientSizeSet from newDimensions
 517             if (newDimensions.isClientSizeSet()) {
 518                 newBounds = new Rectangle(newBounds.x, newBounds.y,
 519                                           newBounds.width - insets.left - insets.right,
 520                                           newBounds.height - insets.top - insets.bottom);
 521             }
 522             newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet());
 523         }
 524         XToolkit.awtLock();
 525         try {
 526             if (!isReparented() || !isVisible()) {
 527                 if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 528                     insLog.fine("- not reparented({0}) or not visible({1}), default reshape",
 529                            Boolean.valueOf(isReparented()), Boolean.valueOf(visible));
 530                 }
 531 
 532                 // Fix for 6323293.
 533                 // This actually is needed to preserve compatibility with previous releases -
 534                 // some of licensees are expecting componentMoved event on invisible one while
 535                 // its location changes.
 536                 Point oldLocation = getLocation();
 537 
 538                 Point newLocation = new Point(AWTAccessor.getComponentAccessor().getX((Component)target),
 539                                               AWTAccessor.getComponentAccessor().getY((Component)target));
 540 
 541                 if (!newLocation.equals(oldLocation)) {
 542                     handleMoved(newDimensions);
 543                 }
 544 
 545                 dimensions = new WindowDimensions(newDimensions);
 546                 updateSizeHints(dimensions);
 547                 Rectangle client = dimensions.getClientRect();


 615               break;
 616           case SET_SIZE:
 617               // Set size sets bounds size. However, until the window is mapped we
 618               // should use client coordinates
 619               dims.setSize(width, height);
 620               break;
 621           case SET_CLIENT_SIZE: {
 622               // Sets client rect size. Width and height contain insets.
 623               Insets in = currentInsets;
 624               width -= in.left+in.right;
 625               height -= in.top+in.bottom;
 626               dims.setClientSize(width, height);
 627               break;
 628           }
 629           case SET_BOUNDS:
 630           default:
 631               dims.setLocation(x, y);
 632               dims.setSize(width, height);
 633               break;
 634         }
 635         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 636             insLog.fine("For the operation {0} new dimensions are {1}",
 637                         operationToString(operation), dims);
 638         }
 639 
 640         reshape(dims, operation, userReshape);
 641     }
 642 
 643     // This method gets overriden in XFramePeer & XDialogPeer.
 644     abstract boolean isTargetUndecorated();
 645 
 646     /**
 647      * @see java.awt.peer.ComponentPeer#setBounds
 648      */
 649     public void setBounds(int x, int y, int width, int height, int op) {
 650         // TODO: Rewrite with WindowDimensions
 651         reshape(x, y, width, height, op, true);
 652         validateSurface();
 653     }
 654 
 655     // Coordinates are that of the shell
 656     void reconfigureContentWindow(WindowDimensions dims) {
 657         if (content == null) {
 658             insLog.fine("WARNING: Content window is null");
 659             return;
 660         }
 661         content.setContentBounds(dims);
 662     }
 663 
 664     boolean no_reparent_artifacts = false;
 665     public void handleConfigureNotifyEvent(XEvent xev) {
 666         assert (SunToolkit.isAWTLockHeldByCurrentThread());
 667         XConfigureEvent xe = xev.get_xconfigure();
 668         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 669             insLog.fine("Configure notify {0}", xe);
 670         }
 671 
 672         // XXX: should really only consider synthetic events, but
 673         if (isReparented()) {
 674             configure_seen = true;
 675         }
 676 
 677         if (!isMaximized()
 678             && (xe.get_serial() == reparent_serial || xe.get_window() != getShell())
 679             && !no_reparent_artifacts)
 680         {
 681             insLog.fine("- reparent artifact, skipping");
 682             return;
 683         }
 684         no_reparent_artifacts = false;
 685 
 686         /**
 687          * When there is a WM we receive some CN before being visible and after.
 688          * We should skip all CN which are before being visible, because we assume
 689          * the gravity is in action while it is not yet.
 690          *
 691          * When there is no WM we receive CN only _before_ being visible.
 692          * We should process these CNs.
 693          */
 694         if (!isVisible() && XWM.getWMID() != XWM.NO_WM) {
 695             insLog.fine(" - not visible, skipping");
 696             return;
 697         }
 698 
 699         /*
 700          * Some window managers configure before we are reparented and
 701          * the send event flag is set! ugh... (Enlighetenment for one,
 702          * possibly MWM as well).  If we haven't been reparented yet
 703          * this is just the WM shuffling us into position.  Ignore
 704          * it!!!! or we wind up in a bogus location.
 705          */
 706         int runningWM = XWM.getWMID();
 707         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 708             insLog.fine("reparented={0}, visible={1}, WM={2}, decorations={3}",
 709                         isReparented(), isVisible(), runningWM, getDecorations());
 710         }
 711         if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
 712                 &&  !XWM.isNonReparentingWM()
 713                 && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
 714             insLog.fine("- visible but not reparented, skipping");
 715             return;
 716         }
 717         //Last chance to correct insets
 718         if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
 719             long parent = XlibUtil.getParentWindow(window);
 720             Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
 721             if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
 722                 if (correctWM != null) {
 723                     insLog.finer("Configure notify - insets : " + correctWM);
 724                 } else {
 725                     insLog.finer("Configure notify - insets are still not available");
 726                 }
 727             }
 728             if (correctWM != null) {
 729                 handleCorrectInsets(correctWM);
 730             } else {
 731                 //Only one attempt to correct insets is made (to lower risk)
 732                 //if insets are still not available we simply set the flag
 733                 insets_corrected = true;
 734             }
 735         }
 736 
 737         updateChildrenSizes();
 738 
 739         // Bounds of the window
 740         Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds((Component)target);
 741 
 742         Point newLocation = targetBounds.getLocation();
 743         if (xe.get_send_event() || runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) {
 744             // Location, Client size + insets
 745             newLocation = new Point(xe.get_x() - currentInsets.left, xe.get_y() - currentInsets.top);
 746         } else {
 747             // ICCCM 4.1.5 states that a real ConfigureNotify will be sent when
 748             // a window is resized but the client can not tell if the window was
 749             // moved or not. The client should consider the position as unkown
 750             // and use TranslateCoordinates to find the actual position.
 751             //
 752             // TODO this should be the default for every case.
 753             switch (XWM.getWMID()) {
 754                 case XWM.CDE_WM:
 755                 case XWM.MOTIF_WM:
 756                 case XWM.METACITY_WM:
 757                 case XWM.MUTTER_WM:
 758                 case XWM.SAWFISH_WM:
 759                 {
 760                     Point xlocation = queryXLocation();
 761                     if (log.isLoggable(PlatformLogger.Level.FINE)) {
 762                         log.fine("New X location: {0}", xlocation);
 763                     }
 764                     if (xlocation != null) {
 765                         newLocation = xlocation;
 766                     }
 767                     break;
 768                 }
 769                 default:
 770                     break;
 771             }
 772         }
 773 
 774         WindowDimensions newDimensions =
 775                 new WindowDimensions(newLocation,
 776                 new Dimension(xe.get_width(), xe.get_height()),
 777                 copy(currentInsets),
 778                 true);
 779 
 780         if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
 781             insLog.finer("Insets are {0}, new dimensions {1}",
 782                      currentInsets, newDimensions);
 783         }
 784 
 785         checkIfOnNewScreen(newDimensions.getBounds());
 786 
 787         Point oldLocation = getLocation();
 788         dimensions = newDimensions;
 789         if (!newLocation.equals(oldLocation)) {
 790             handleMoved(newDimensions);
 791         }
 792         reconfigureContentWindow(newDimensions);
 793         updateChildrenSizes();
 794 
 795         repositionSecurityWarning();
 796     }
 797 
 798     private void checkShellRectSize(Rectangle shellRect) {
 799         shellRect.width = Math.max(MIN_SIZE, shellRect.width);
 800         shellRect.height = Math.max(MIN_SIZE, shellRect.height);
 801     }
 802 
 803     private void checkShellRectPos(Rectangle shellRect) {
 804         int wm = XWM.getWMID();
 805         if (wm == XWM.MOTIF_WM || wm == XWM.CDE_WM) {
 806             if (shellRect.x == 0 && shellRect.y == 0) {
 807                 shellRect.x = shellRect.y = 1;
 808             }
 809         }
 810     }
 811 
 812     private void checkShellRect(Rectangle shellRect) {
 813         checkShellRectSize(shellRect);
 814         checkShellRectPos(shellRect);
 815     }
 816 
 817     public void setShellBounds(Rectangle rec) {
 818         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 819             insLog.fine("Setting shell bounds on " + this + " to " + rec);
 820         }
 821         XToolkit.awtLock();
 822         try {
 823             updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 824             XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
 825             XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
 826         }
 827         finally {
 828             XToolkit.awtUnlock();
 829         }
 830     }
 831     public void setShellSize(Rectangle rec) {
 832         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 833             insLog.fine("Setting shell size on " + this + " to " + rec);
 834         }
 835         XToolkit.awtLock();
 836         try {
 837             updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 838             XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), rec.width, rec.height);
 839         }
 840         finally {
 841             XToolkit.awtUnlock();
 842         }
 843     }
 844     public void setShellPosition(Rectangle rec) {
 845         if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 846             insLog.fine("Setting shell position on " + this + " to " + rec);
 847         }
 848         XToolkit.awtLock();
 849         try {
 850             updateSizeHints(rec.x, rec.y, rec.width, rec.height);
 851             XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), rec.x, rec.y);
 852         }
 853         finally {
 854             XToolkit.awtUnlock();
 855         }
 856     }
 857 
 858     void initResizability() {
 859         setResizable(winAttr.initialResizability);
 860     }
 861     public void setResizable(boolean resizable) {
 862         int fs = winAttr.functions;
 863         if (!isResizable() && resizable) {
 864             currentInsets = new Insets(0, 0, 0, 0);
 865             resetWMSetInsets();


 927 
 928     public int getWidth() {
 929         return getSize().width;
 930     }
 931 
 932     public int getHeight() {
 933         return getSize().height;
 934     }
 935 
 936     final public WindowDimensions getDimensions() {
 937         return dimensions;
 938     }
 939 
 940     public Point getLocationOnScreen() {
 941         XToolkit.awtLock();
 942         try {
 943             if (configure_seen) {
 944                 return toGlobal(0,0);
 945             } else {
 946                 Point location = target.getLocation();
 947                 if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
 948                     insLog.fine("getLocationOnScreen {0} not reparented: {1} ",
 949                                 this, location);
 950                 }
 951                 return location;
 952             }
 953         } finally {
 954             XToolkit.awtUnlock();
 955         }
 956     }
 957 
 958 
 959 /***************************************************************************************
 960  *              END            OF             I N S E T S   C O D E
 961  **************************************************************************************/
 962 
 963     protected boolean isEventDisabled(XEvent e) {
 964         switch (e.get_type()) {
 965             // Do not generate MOVED/RESIZED events since we generate them by ourselves
 966           case XConstants.ConfigureNotify:
 967               return true;
 968           case XConstants.EnterNotify:
 969           case XConstants.LeaveNotify:
 970               // Disable crossing event on outer borders of Frame so
 971               // we receive only one set of cross notifications(first set is from content window)
 972               return true;
 973           default:
 974               return super.isEventDisabled(e);
 975         }
 976     }
 977 
 978     int getDecorations() {
 979         return winAttr.decorations;
 980     }
 981 
 982     int getFunctions() {
 983         return winAttr.functions;
 984     }
 985 
 986     public void setVisible(boolean vis) {
 987         if (log.isLoggable(PlatformLogger.Level.FINER)) {
 988             log.finer("Setting {0} to visible {1}", this, Boolean.valueOf(vis));
 989         }
 990         if (vis && !isVisible()) {
 991             XWM.setShellDecor(this);
 992             super.setVisible(vis);
 993             if (winAttr.isResizable) {
 994                 //Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.
 995                 //We need to update frame's minimum size, not to reset it
 996                 XWM.removeSizeHints(this, XUtilConstants.PMaxSize);
 997                 updateMinimumSize();
 998             }
 999         } else {
1000             super.setVisible(vis);
1001         }
1002     }
1003 
1004     protected void suppressWmTakeFocus(boolean doSuppress) {
1005         XAtomList protocols = getWMProtocols();
1006         if (doSuppress) {
1007             protocols.remove(wm_take_focus);


1020         if (iconWindow != null) {
1021             iconWindow.destroy();
1022         }
1023 
1024         super.dispose();
1025     }
1026 
1027     public void handleClientMessage(XEvent xev) {
1028         super.handleClientMessage(xev);
1029         XClientMessageEvent cl = xev.get_xclient();
1030         if ((wm_protocols != null) && (cl.get_message_type() == wm_protocols.getAtom())) {
1031             if (cl.get_data(0) == wm_delete_window.getAtom()) {
1032                 handleQuit();
1033             } else if (cl.get_data(0) == wm_take_focus.getAtom()) {
1034                 handleWmTakeFocus(cl);
1035             }
1036         }
1037     }
1038 
1039     private void handleWmTakeFocus(XClientMessageEvent cl) {
1040         if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
1041             focusLog.fine("WM_TAKE_FOCUS on {0}", this);
1042         }
1043         requestWindowFocus(cl.get_data(1), true);
1044     }
1045 
1046     /**
1047      * Requests focus to this decorated top-level by requesting X input focus
1048      * to the shell window.
1049      */
1050     protected void requestXFocus(long time, boolean timeProvided) {
1051         // We have proxied focus mechanism - instead of shell the focus is held
1052         // by "proxy" - invisible mapped window. When we want to set X input focus to
1053         // toplevel set it on proxy instead.
1054         if (focusProxy == null) {
1055             if (focusLog.isLoggable(PlatformLogger.Level.WARNING)) {
1056                 focusLog.warning("Focus proxy is null for " + this);
1057             }
1058         } else {
1059             if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
1060                 focusLog.fine("Requesting focus to proxy: " + focusProxy);
1061             }
1062             if (timeProvided) {
1063                 focusProxy.xRequestFocus(time);
1064             } else {
1065                 focusProxy.xRequestFocus();
1066             }
1067         }
1068     }
1069 
1070     XFocusProxyWindow getFocusProxy() {
1071         return focusProxy;
1072     }
1073 
1074     public void handleQuit() {
1075         postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_CLOSING));
1076     }
1077 
1078     final void dumpMe() {
1079         System.err.println(">>> Peer: " + x + ", " + y + ", " + width + ", " + height);


1133         dumpShell();
1134         dumpContent();
1135     }
1136 
1137     boolean isMaximized() {
1138         return false;
1139     }
1140 
1141     @Override
1142     boolean isOverrideRedirect() {
1143         return Window.Type.POPUP.equals(getWindowType());
1144     }
1145 
1146     public boolean requestWindowFocus(long time, boolean timeProvided) {
1147         focusLog.fine("Request for decorated window focus");
1148         // If this is Frame or Dialog we can't assure focus request success - but we still can try
1149         // If this is Window and its owner Frame is active we can be sure request succedded.
1150         Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
1151         Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
1152 
1153         if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
1154             focusLog.finer("Current window is: active={0}, focused={1}",
1155                        Boolean.valueOf(target == activeWindow),
1156                        Boolean.valueOf(target == focusedWindow));
1157         }
1158 
1159         XWindowPeer toFocus = this;
1160         while (toFocus.nextTransientFor != null) {
1161             toFocus = toFocus.nextTransientFor;
1162         }
1163         if (toFocus == null || !toFocus.focusAllowedFor()) {
1164             // This might change when WM will have property to determine focus policy.
1165             // Right now, because policy is unknown we can't be sure we succedded
1166             return false;
1167         }
1168         if (this == toFocus) {
1169             if (isWMStateNetHidden()) {
1170                 focusLog.fine("The window is unmapped, so rejecting the request");
1171                 return false;
1172             }
1173             if (target == activeWindow && target != focusedWindow) {
1174                 // Happens when an owned window is currently focused
1175                 focusLog.fine("Focus is on child window - transfering it back to the owner");
1176                 handleWindowFocusInSync(-1);
1177                 return true;
1178             }
1179             Window realNativeFocusedWindow = XWindowPeer.getNativeFocusedWindow();
1180             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
1181                 focusLog.finest("Real native focused window: " + realNativeFocusedWindow +
1182                             "\nKFM's focused window: " + focusedWindow);
1183             }
1184 
1185             // A workaround for Metacity. See 6522725, 6613426, 7147075.
1186             if (target == realNativeFocusedWindow && XWM.getWMID() == XWM.METACITY_WM) {
1187                 if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
1188                     focusLog.fine("The window is already natively focused.");
1189                 }
1190                 return true;
1191             }
1192         }
1193         if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
1194             focusLog.fine("Requesting focus to " + (this == toFocus ? "this window" : toFocus));
1195         }
1196 
1197         if (timeProvided) {
1198             toFocus.requestXFocus(time);
1199         } else {
1200             toFocus.requestXFocus();
1201         }
1202         return (this == toFocus);
1203     }
1204 
1205     XWindowPeer actualFocusedWindow = null;
1206     void setActualFocusedWindow(XWindowPeer actualFocusedWindow) {
1207         synchronized(getStateLock()) {
1208             this.actualFocusedWindow = actualFocusedWindow;
1209         }
1210     }
1211 
1212     boolean requestWindowFocus(XWindowPeer actualFocusedWindow,
1213                                long time, boolean timeProvided)