< prev index next >

src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java

Print this page




 405     /**
 406      * Returns whether there is last remembered cursor position.  The
 407      * position is remembered from X mouse events on our peers.  The
 408      * position is stored in <code>p</code>.
 409      * @return true, if there is remembered last cursor position,
 410      * false otherwise
 411      */
 412     boolean getLastCursorPos(Point p) {
 413         awtLock();
 414         try {
 415             if (lastCursorPos == null) {
 416                 return false;
 417             }
 418             p.setLocation(lastCursorPos);
 419             return true;
 420         } finally {
 421             awtUnlock();
 422         }
 423     }
 424 
 425     private void processGlobalMotionEvent(XEvent e) {
 426         // Only our windows guaranteely generate MotionNotify, so we
 427         // should track enter/leave, to catch the moment when to
 428         // switch to XQueryPointer
 429         if (e.get_type() == XConstants.MotionNotify) {
 430             XMotionEvent ev = e.get_xmotion();
 431             awtLock();
 432             try {
 433                 if (lastCursorPos == null) {
 434                     lastCursorPos = new Point(ev.get_x_root(), ev.get_y_root());

 435                 } else {
 436                     lastCursorPos.setLocation(ev.get_x_root(), ev.get_y_root());

 437                 }
 438             } finally {
 439                 awtUnlock();
 440             }
 441         } else if (e.get_type() == XConstants.LeaveNotify) {
 442             // Leave from our window
 443             awtLock();
 444             try {
 445                 lastCursorPos = null;
 446             } finally {
 447                 awtUnlock();
 448             }
 449         } else if (e.get_type() == XConstants.EnterNotify) {
 450             // Entrance into our window
 451             XCrossingEvent ev = e.get_xcrossing();
 452             awtLock();
 453             try {
 454                 if (lastCursorPos == null) {
 455                     lastCursorPos = new Point(ev.get_x_root(), ev.get_y_root());

 456                 } else {
 457                     lastCursorPos.setLocation(ev.get_x_root(), ev.get_y_root());

 458                 }
 459             } finally {
 460                 awtUnlock();
 461             }
 462         }
 463     }
 464 
 465     public interface XEventListener {
 466         public void eventProcessed(XEvent e);
 467     }
 468 
 469     private Collection<XEventListener> listeners = new LinkedList<XEventListener>();
 470 
 471     public void addXEventListener(XEventListener listener) {
 472         synchronized (listeners) {
 473             listeners.add(listener);
 474         }
 475     }
 476 
 477     private void notifyListeners(XEvent xev) {
 478         synchronized (listeners) {
 479             if (listeners.size() == 0) return;
 480 
 481             XEvent copy = xev.clone();
 482             try {
 483                 for (XEventListener listener : listeners) {
 484                     listener.eventProcessed(copy);
 485                 }
 486             } finally {
 487                 copy.dispose();
 488             }
 489         }
 490     }
 491 
 492     private void dispatchEvent(XEvent ev) {
 493         final XAnyEvent xany = ev.get_xany();
 494 
 495         if (windowToXWindow(xany.get_window()) != null &&
 496              (ev.get_type() == XConstants.MotionNotify || ev.get_type() == XConstants.EnterNotify || ev.get_type() == XConstants.LeaveNotify))
 497         {
 498             processGlobalMotionEvent(ev);

 499         }
 500 
 501         if( ev.get_type() == XConstants.MappingNotify ) {
 502             // The 'window' field in this event is unused.
 503             // This application itself does nothing to initiate such an event
 504             // (no calls of XChangeKeyboardMapping etc.).
 505             // SunRay server sends this event to the application once on every
 506             // keyboard (not just layout) change which means, quite seldom.
 507             XlibWrapper.XRefreshKeyboardMapping(ev.pData);
 508             resetKeyboardSniffer();
 509             setupModifierMap();
 510         }
 511         XBaseWindow.dispatchToWindow(ev);
 512 
 513         Collection<XEventDispatcher> dispatchers = null;
 514         synchronized(winToDispatcher) {
 515             Long key = Long.valueOf(xany.get_window());
 516             dispatchers = winToDispatcher.get(key);
 517             if (dispatchers != null) { // Clone it to avoid synchronization during dispatching
 518                 dispatchers = new Vector<>(dispatchers);


 684     static int getDefaultScreenWidth() {
 685         initScreenSize();
 686         return screenWidth;
 687     }
 688 
 689     static int getDefaultScreenHeight() {
 690         initScreenSize();
 691         return screenHeight;
 692     }
 693 
 694     @Override
 695     protected int getScreenWidth() {
 696         return getDefaultScreenWidth();
 697     }
 698 
 699     @Override
 700     protected int getScreenHeight() {
 701         return getDefaultScreenHeight();
 702     }
 703 
 704     private static Rectangle getWorkArea(long root)
 705     {
 706         XAtom XA_NET_WORKAREA = XAtom.get("_NET_WORKAREA");
 707 
 708         long native_ptr = Native.allocateLongArray(4);
 709         try
 710         {
 711             boolean workareaPresent = XA_NET_WORKAREA.getAtomData(root,
 712                 XAtom.XA_CARDINAL, native_ptr, 4);
 713             if (workareaPresent)
 714             {
 715                 int rootX = (int)Native.getLong(native_ptr, 0);
 716                 int rootY = (int)Native.getLong(native_ptr, 1);
 717                 int rootWidth = (int)Native.getLong(native_ptr, 2);
 718                 int rootHeight = (int)Native.getLong(native_ptr, 3);
 719 
 720                 return new Rectangle(rootX, rootY, rootWidth, rootHeight);

 721             }
 722         }
 723         finally
 724         {
 725             XlibWrapper.unsafe.freeMemory(native_ptr);
 726         }
 727 
 728         return null;
 729     }
 730 
 731     /*
 732      * If we're running in non-Xinerama environment and the current
 733      * window manager supports _NET protocol then the screen insets
 734      * are calculated using _NET_WM_WORKAREA property of the root
 735      * window.
 736      * Otherwise, i. e. if Xinerama is on or _NET_WM_WORKAREA is
 737      * not set, we try to calculate the insets ourselves using
 738      * getScreenInsetsManually method.
 739      */
 740     @Override
 741     public Insets getScreenInsets(GraphicsConfiguration gc)
 742     {
 743         XNETProtocol netProto = XWM.getWM().getNETProtocol();
 744         if ((netProto == null) || !netProto.active())
 745         {
 746             return super.getScreenInsets(gc);
 747         }
 748 
 749         XToolkit.awtLock();
 750         try
 751         {
 752             X11GraphicsConfig x11gc = (X11GraphicsConfig)gc;
 753             X11GraphicsDevice x11gd = (X11GraphicsDevice)x11gc.getDevice();
 754             long root = XlibUtil.getRootWindow(x11gd.getScreen());
 755             Rectangle rootBounds = XlibUtil.getWindowGeometry(root);

 756 
 757             X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
 758                 GraphicsEnvironment.getLocalGraphicsEnvironment();
 759             if (!x11ge.runningXinerama())
 760             {
 761                 Rectangle workArea = XToolkit.getWorkArea(root);
 762                 if (workArea != null)
 763                 {
 764                     return new Insets(workArea.y,
 765                                       workArea.x,
 766                                       rootBounds.height - workArea.height - workArea.y,
 767                                       rootBounds.width - workArea.width - workArea.x);
 768                 }
 769             }
 770 
 771             return getScreenInsetsManually(root, rootBounds, gc.getBounds());
 772         }
 773         finally
 774         {
 775             XToolkit.awtUnlock();
 776         }
 777     }
 778 
 779     /*
 780      * Manual calculation of screen insets: get all the windows with
 781      * _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these
 782      * hints' values to screen insets.
 783      *
 784      * This method should be called under XToolkit.awtLock()
 785      */
 786     private Insets getScreenInsetsManually(long root, Rectangle rootBounds, Rectangle screenBounds)

 787     {
 788         /*
 789          * During the manual calculation of screen insets we iterate
 790          * all the X windows hierarchy starting from root window. This
 791          * constant is the max level inspected in this hierarchy.
 792          * 3 is a heuristic value: I suppose any the toolbar-like
 793          * window is a child of either root or desktop window.
 794          */
 795         final int MAX_NESTED_LEVEL = 3;
 796 
 797         XAtom XA_NET_WM_STRUT = XAtom.get("_NET_WM_STRUT");
 798         XAtom XA_NET_WM_STRUT_PARTIAL = XAtom.get("_NET_WM_STRUT_PARTIAL");
 799 
 800         Insets insets = new Insets(0, 0, 0, 0);
 801 
 802         java.util.List<Object> search = new LinkedList<>();
 803         search.add(root);
 804         search.add(0);
 805         while (!search.isEmpty())
 806         {


 814              * are not included to the screen insets.
 815              */
 816             if (XlibUtil.getWindowMapState(window) == XConstants.IsUnmapped)
 817             {
 818                 continue;
 819             }
 820 
 821             long native_ptr = Native.allocateLongArray(4);
 822             try
 823             {
 824                 // first, check if _NET_WM_STRUT or _NET_WM_STRUT_PARTIAL are present
 825                 // if both are set on the window, _NET_WM_STRUT_PARTIAL is used (see _NET spec)
 826                 boolean strutPresent = XA_NET_WM_STRUT_PARTIAL.getAtomData(window, XAtom.XA_CARDINAL, native_ptr, 4);
 827                 if (!strutPresent)
 828                 {
 829                     strutPresent = XA_NET_WM_STRUT.getAtomData(window, XAtom.XA_CARDINAL, native_ptr, 4);
 830                 }
 831                 if (strutPresent)
 832                 {
 833                     // second, verify that window is located on the proper screen
 834                     Rectangle windowBounds = XlibUtil.getWindowGeometry(window);

 835                     if (windowLevel > 1)
 836                     {
 837                         windowBounds = XlibUtil.translateCoordinates(window, root, windowBounds);


 838                     }
 839                     // if _NET_WM_STRUT_PARTIAL is present, we should use its values to detect
 840                     // if the struts area intersects with screenBounds, however some window
 841                     // managers don't set this hint correctly, so we just get intersection with windowBounds
 842                     if (windowBounds != null && windowBounds.intersects(screenBounds))
 843                     {
 844                         int left = (int)Native.getLong(native_ptr, 0);
 845                         int right = (int)Native.getLong(native_ptr, 1);
 846                         int top = (int)Native.getLong(native_ptr, 2);
 847                         int bottom = (int)Native.getLong(native_ptr, 3);
 848 
 849                         /*
 850                          * struts could be relative to root window bounds, so
 851                          * make them relative to the screen bounds in this case
 852                          */
 853                         left = rootBounds.x + left > screenBounds.x ?
 854                                 rootBounds.x + left - screenBounds.x : 0;
 855                         right = rootBounds.x + rootBounds.width - right <
 856                                 screenBounds.x + screenBounds.width ?
 857                                 screenBounds.x + screenBounds.width -
 858                                 (rootBounds.x + rootBounds.width - right) : 0;
 859                         top = rootBounds.y + top > screenBounds.y ?
 860                                 rootBounds.y + top - screenBounds.y : 0;
 861                         bottom = rootBounds.y + rootBounds.height - bottom <
 862                                 screenBounds.y + screenBounds.height ?
 863                                 screenBounds.y + screenBounds.height -
 864                                 (rootBounds.y + rootBounds.height - bottom) : 0;
 865 
 866                         insets.left = Math.max(left, insets.left);
 867                         insets.right = Math.max(right, insets.right);


2470         if (oops_waiter == null) {
2471             oops_waiter = new XEventDispatcher() {
2472                     @Override
2473                     public void dispatchEvent(XEvent e) {
2474                         if (e.get_type() == XConstants.ConfigureNotify) {
2475                             // OOPS ConfigureNotify event catched
2476                             oops_updated = true;
2477                             awtLockNotifyAll();
2478                         }
2479                     }
2480                 };
2481         }
2482 
2483         awtLock();
2484         try {
2485             addEventDispatcher(win.getWindow(), oops_waiter);
2486 
2487             oops_updated = false;
2488             long event_number = getEventNumber();
2489             // Generate OOPS ConfigureNotify event
2490             XlibWrapper.XMoveWindow(getDisplay(), win.getWindow(), ++oops_position, 0);

2491             // Change win position each time to avoid system optimization
2492             if (oops_position > 50) {
2493                 oops_position = 0;
2494             }
2495 
2496             XSync();
2497 
2498             eventLog.finer("Generated OOPS ConfigureNotify event");
2499 
2500             long start = System.currentTimeMillis();
2501             while (!oops_updated) {
2502                 try {
2503                     // Wait for OOPS ConfigureNotify event
2504                     awtLockWait(timeout);
2505                 } catch (InterruptedException e) {
2506                     throw new RuntimeException(e);
2507                 }
2508                 // This "while" is a protection from spurious
2509                 // wake-ups.  However, we shouldn't wait for too long
2510                 if ((System.currentTimeMillis() - start > timeout) && timeout >= 0) {




 405     /**
 406      * Returns whether there is last remembered cursor position.  The
 407      * position is remembered from X mouse events on our peers.  The
 408      * position is stored in <code>p</code>.
 409      * @return true, if there is remembered last cursor position,
 410      * false otherwise
 411      */
 412     boolean getLastCursorPos(Point p) {
 413         awtLock();
 414         try {
 415             if (lastCursorPos == null) {
 416                 return false;
 417             }
 418             p.setLocation(lastCursorPos);
 419             return true;
 420         } finally {
 421             awtUnlock();
 422         }
 423     }
 424 
 425     private void processGlobalMotionEvent(XEvent e, XBaseWindow win) {
 426         // Only our windows guaranteely generate MotionNotify, so we
 427         // should track enter/leave, to catch the moment when to
 428         // switch to XQueryPointer
 429         if (e.get_type() == XConstants.MotionNotify) {
 430             XMotionEvent ev = e.get_xmotion();
 431             awtLock();
 432             try {
 433                 if (lastCursorPos == null) {
 434                     lastCursorPos = new Point(win.scaleDown(ev.get_x_root()),
 435                                               win.scaleDown(ev.get_y_root()));
 436                 } else {
 437                     lastCursorPos.setLocation(win.scaleDown(ev.get_x_root()),
 438                                               win.scaleDown(ev.get_y_root()));
 439                 }
 440             } finally {
 441                 awtUnlock();
 442             }
 443         } else if (e.get_type() == XConstants.LeaveNotify) {
 444             // Leave from our window
 445             awtLock();
 446             try {
 447                 lastCursorPos = null;
 448             } finally {
 449                 awtUnlock();
 450             }
 451         } else if (e.get_type() == XConstants.EnterNotify) {
 452             // Entrance into our window
 453             XCrossingEvent ev = e.get_xcrossing();
 454             awtLock();
 455             try {
 456                 if (lastCursorPos == null) {
 457                     lastCursorPos = new Point(win.scaleDown(ev.get_x_root()),
 458                                               win.scaleDown(ev.get_y_root()));
 459                 } else {
 460                     lastCursorPos.setLocation(win.scaleDown(ev.get_x_root()),
 461                                               win.scaleDown(ev.get_y_root()));
 462                 }
 463             } finally {
 464                 awtUnlock();
 465             }
 466         }
 467     }
 468 
 469     public interface XEventListener {
 470         public void eventProcessed(XEvent e);
 471     }
 472 
 473     private Collection<XEventListener> listeners = new LinkedList<XEventListener>();
 474 
 475     public void addXEventListener(XEventListener listener) {
 476         synchronized (listeners) {
 477             listeners.add(listener);
 478         }
 479     }
 480 
 481     private void notifyListeners(XEvent xev) {
 482         synchronized (listeners) {
 483             if (listeners.size() == 0) return;
 484 
 485             XEvent copy = xev.clone();
 486             try {
 487                 for (XEventListener listener : listeners) {
 488                     listener.eventProcessed(copy);
 489                 }
 490             } finally {
 491                 copy.dispose();
 492             }
 493         }
 494     }
 495 
 496     private void dispatchEvent(XEvent ev) {
 497         final XAnyEvent xany = ev.get_xany();
 498 
 499         XBaseWindow baseWindow = windowToXWindow(xany.get_window());
 500         if (baseWindow != null && (ev.get_type() == XConstants.MotionNotify
 501                 || ev.get_type() == XConstants.EnterNotify
 502                 || ev.get_type() == XConstants.LeaveNotify)) {
 503             processGlobalMotionEvent(ev, baseWindow);
 504         }
 505 
 506         if( ev.get_type() == XConstants.MappingNotify ) {
 507             // The 'window' field in this event is unused.
 508             // This application itself does nothing to initiate such an event
 509             // (no calls of XChangeKeyboardMapping etc.).
 510             // SunRay server sends this event to the application once on every
 511             // keyboard (not just layout) change which means, quite seldom.
 512             XlibWrapper.XRefreshKeyboardMapping(ev.pData);
 513             resetKeyboardSniffer();
 514             setupModifierMap();
 515         }
 516         XBaseWindow.dispatchToWindow(ev);
 517 
 518         Collection<XEventDispatcher> dispatchers = null;
 519         synchronized(winToDispatcher) {
 520             Long key = Long.valueOf(xany.get_window());
 521             dispatchers = winToDispatcher.get(key);
 522             if (dispatchers != null) { // Clone it to avoid synchronization during dispatching
 523                 dispatchers = new Vector<>(dispatchers);


 689     static int getDefaultScreenWidth() {
 690         initScreenSize();
 691         return screenWidth;
 692     }
 693 
 694     static int getDefaultScreenHeight() {
 695         initScreenSize();
 696         return screenHeight;
 697     }
 698 
 699     @Override
 700     protected int getScreenWidth() {
 701         return getDefaultScreenWidth();
 702     }
 703 
 704     @Override
 705     protected int getScreenHeight() {
 706         return getDefaultScreenHeight();
 707     }
 708 
 709     private static Rectangle getWorkArea(long root, int scale)
 710     {
 711         XAtom XA_NET_WORKAREA = XAtom.get("_NET_WORKAREA");
 712 
 713         long native_ptr = Native.allocateLongArray(4);
 714         try
 715         {
 716             boolean workareaPresent = XA_NET_WORKAREA.getAtomData(root,
 717                 XAtom.XA_CARDINAL, native_ptr, 4);
 718             if (workareaPresent)
 719             {
 720                 int rootX = (int)Native.getLong(native_ptr, 0);
 721                 int rootY = (int)Native.getLong(native_ptr, 1);
 722                 int rootWidth = (int)Native.getLong(native_ptr, 2);
 723                 int rootHeight = (int)Native.getLong(native_ptr, 3);
 724 
 725                 return new Rectangle(rootX / scale, rootY / scale,
 726                                      rootWidth / scale, rootHeight / scale);
 727             }
 728         }
 729         finally
 730         {
 731             XlibWrapper.unsafe.freeMemory(native_ptr);
 732         }
 733 
 734         return null;
 735     }
 736 
 737     /*
 738      * If we're running in non-Xinerama environment and the current
 739      * window manager supports _NET protocol then the screen insets
 740      * are calculated using _NET_WM_WORKAREA property of the root
 741      * window.
 742      * Otherwise, i. e. if Xinerama is on or _NET_WM_WORKAREA is
 743      * not set, we try to calculate the insets ourselves using
 744      * getScreenInsetsManually method.
 745      */
 746     @Override
 747     public Insets getScreenInsets(GraphicsConfiguration gc)
 748     {
 749         XNETProtocol netProto = XWM.getWM().getNETProtocol();
 750         if ((netProto == null) || !netProto.active())
 751         {
 752             return super.getScreenInsets(gc);
 753         }
 754 
 755         XToolkit.awtLock();
 756         try
 757         {
 758             X11GraphicsConfig x11gc = (X11GraphicsConfig)gc;
 759             X11GraphicsDevice x11gd = x11gc.getDevice();
 760             long root = XlibUtil.getRootWindow(x11gd.getScreen());
 761             int scale = x11gc.getScale();
 762             Rectangle rootBounds = XlibUtil.getWindowGeometry(root, scale);
 763 
 764             X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
 765                 GraphicsEnvironment.getLocalGraphicsEnvironment();
 766             if (!x11ge.runningXinerama())
 767             {
 768                 Rectangle workArea = XToolkit.getWorkArea(root, scale);
 769                 if (workArea != null)
 770                 {
 771                     return new Insets(workArea.y,
 772                                       workArea.x,
 773                                       rootBounds.height - workArea.height - workArea.y,
 774                                       rootBounds.width - workArea.width - workArea.x);
 775                 }
 776             }
 777 
 778             return getScreenInsetsManually(root, rootBounds, gc.getBounds(), scale);
 779         }
 780         finally
 781         {
 782             XToolkit.awtUnlock();
 783         }
 784     }
 785 
 786     /*
 787      * Manual calculation of screen insets: get all the windows with
 788      * _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these
 789      * hints' values to screen insets.
 790      *
 791      * This method should be called under XToolkit.awtLock()
 792      */
 793     private Insets getScreenInsetsManually(long root, Rectangle rootBounds,
 794                                            Rectangle screenBounds, int scale)
 795     {
 796         /*
 797          * During the manual calculation of screen insets we iterate
 798          * all the X windows hierarchy starting from root window. This
 799          * constant is the max level inspected in this hierarchy.
 800          * 3 is a heuristic value: I suppose any the toolbar-like
 801          * window is a child of either root or desktop window.
 802          */
 803         final int MAX_NESTED_LEVEL = 3;
 804 
 805         XAtom XA_NET_WM_STRUT = XAtom.get("_NET_WM_STRUT");
 806         XAtom XA_NET_WM_STRUT_PARTIAL = XAtom.get("_NET_WM_STRUT_PARTIAL");
 807 
 808         Insets insets = new Insets(0, 0, 0, 0);
 809 
 810         java.util.List<Object> search = new LinkedList<>();
 811         search.add(root);
 812         search.add(0);
 813         while (!search.isEmpty())
 814         {


 822              * are not included to the screen insets.
 823              */
 824             if (XlibUtil.getWindowMapState(window) == XConstants.IsUnmapped)
 825             {
 826                 continue;
 827             }
 828 
 829             long native_ptr = Native.allocateLongArray(4);
 830             try
 831             {
 832                 // first, check if _NET_WM_STRUT or _NET_WM_STRUT_PARTIAL are present
 833                 // if both are set on the window, _NET_WM_STRUT_PARTIAL is used (see _NET spec)
 834                 boolean strutPresent = XA_NET_WM_STRUT_PARTIAL.getAtomData(window, XAtom.XA_CARDINAL, native_ptr, 4);
 835                 if (!strutPresent)
 836                 {
 837                     strutPresent = XA_NET_WM_STRUT.getAtomData(window, XAtom.XA_CARDINAL, native_ptr, 4);
 838                 }
 839                 if (strutPresent)
 840                 {
 841                     // second, verify that window is located on the proper screen
 842                     Rectangle windowBounds = XlibUtil.getWindowGeometry(window,
 843                                                                         scale);
 844                     if (windowLevel > 1)
 845                     {
 846                         windowBounds = XlibUtil.translateCoordinates(window, root,
 847                                                                      windowBounds,
 848                                                                      scale);
 849                     }
 850                     // if _NET_WM_STRUT_PARTIAL is present, we should use its values to detect
 851                     // if the struts area intersects with screenBounds, however some window
 852                     // managers don't set this hint correctly, so we just get intersection with windowBounds
 853                     if (windowBounds != null && windowBounds.intersects(screenBounds))
 854                     {
 855                         int left = (int)Native.getLong(native_ptr, 0) / scale;
 856                         int right = (int)Native.getLong(native_ptr, 1) / scale;
 857                         int top = (int)Native.getLong(native_ptr, 2) / scale;
 858                         int bottom = (int)Native.getLong(native_ptr, 3) / scale;
 859 
 860                         /*
 861                          * struts could be relative to root window bounds, so
 862                          * make them relative to the screen bounds in this case
 863                          */
 864                         left = rootBounds.x + left > screenBounds.x ?
 865                                 rootBounds.x + left - screenBounds.x : 0;
 866                         right = rootBounds.x + rootBounds.width - right <
 867                                 screenBounds.x + screenBounds.width ?
 868                                 screenBounds.x + screenBounds.width -
 869                                 (rootBounds.x + rootBounds.width - right) : 0;
 870                         top = rootBounds.y + top > screenBounds.y ?
 871                                 rootBounds.y + top - screenBounds.y : 0;
 872                         bottom = rootBounds.y + rootBounds.height - bottom <
 873                                 screenBounds.y + screenBounds.height ?
 874                                 screenBounds.y + screenBounds.height -
 875                                 (rootBounds.y + rootBounds.height - bottom) : 0;
 876 
 877                         insets.left = Math.max(left, insets.left);
 878                         insets.right = Math.max(right, insets.right);


2481         if (oops_waiter == null) {
2482             oops_waiter = new XEventDispatcher() {
2483                     @Override
2484                     public void dispatchEvent(XEvent e) {
2485                         if (e.get_type() == XConstants.ConfigureNotify) {
2486                             // OOPS ConfigureNotify event catched
2487                             oops_updated = true;
2488                             awtLockNotifyAll();
2489                         }
2490                     }
2491                 };
2492         }
2493 
2494         awtLock();
2495         try {
2496             addEventDispatcher(win.getWindow(), oops_waiter);
2497 
2498             oops_updated = false;
2499             long event_number = getEventNumber();
2500             // Generate OOPS ConfigureNotify event
2501             XlibWrapper.XMoveWindow(getDisplay(), win.getWindow(),
2502                                     win.scaleUp(++oops_position), 0);
2503             // Change win position each time to avoid system optimization
2504             if (oops_position > 50) {
2505                 oops_position = 0;
2506             }
2507 
2508             XSync();
2509 
2510             eventLog.finer("Generated OOPS ConfigureNotify event");
2511 
2512             long start = System.currentTimeMillis();
2513             while (!oops_updated) {
2514                 try {
2515                     // Wait for OOPS ConfigureNotify event
2516                     awtLockWait(timeout);
2517                 } catch (InterruptedException e) {
2518                     throw new RuntimeException(e);
2519                 }
2520                 // This "while" is a protection from spurious
2521                 // wake-ups.  However, we shouldn't wait for too long
2522                 if ((System.currentTimeMillis() - start > timeout) && timeout >= 0) {


< prev index next >