< prev index next >

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

Print this page




 104 import java.awt.peer.RobotPeer;
 105 import java.awt.peer.ScrollPanePeer;
 106 import java.awt.peer.ScrollbarPeer;
 107 import java.awt.peer.SystemTrayPeer;
 108 import java.awt.peer.TaskbarPeer;
 109 import java.awt.peer.TextAreaPeer;
 110 import java.awt.peer.TextFieldPeer;
 111 import java.awt.peer.TrayIconPeer;
 112 import java.awt.peer.WindowPeer;
 113 import java.beans.PropertyChangeListener;
 114 import java.security.AccessController;
 115 import java.security.PrivilegedAction;
 116 import java.util.ArrayList;
 117 import java.util.Collection;
 118 import java.util.HashMap;
 119 import java.util.Iterator;
 120 import java.util.LinkedList;
 121 import java.util.Map;
 122 import java.util.NoSuchElementException;
 123 import java.util.Properties;
 124 import java.util.Set;
 125 import java.util.SortedMap;
 126 import java.util.TreeMap;
 127 import java.util.Vector;
 128 
 129 import javax.swing.LookAndFeel;
 130 import javax.swing.UIDefaults;
 131 
 132 import sun.awt.AWTAccessor;
 133 import sun.awt.AWTPermissions;
 134 import sun.awt.AppContext;
 135 import sun.awt.DisplayChangedListener;
 136 import sun.awt.LightweightFrame;
 137 import sun.awt.SunToolkit;
 138 import sun.awt.UNIXToolkit;
 139 import sun.awt.X11GraphicsConfig;
 140 import sun.awt.X11GraphicsDevice;
 141 import sun.awt.X11GraphicsEnvironment;
 142 import sun.awt.XSettings;
 143 import sun.awt.datatransfer.DataTransferer;
 144 import sun.awt.util.PerformanceLogger;


 196     static int arrowCursor;
 197     static TreeMap<Long, XBaseWindow> winMap = new TreeMap<>();
 198     static HashMap<Object, Object> specialPeerMap = new HashMap<>();
 199     static HashMap<Long, Collection<XEventDispatcher>> winToDispatcher = new HashMap<>();
 200     static UIDefaults uidefaults;
 201     static final X11GraphicsEnvironment localEnv;
 202     private static final X11GraphicsDevice device;
 203     private static final long display;
 204     static int awt_multiclick_time;
 205     static boolean securityWarningEnabled;
 206 
 207     /**
 208      * Dimensions of default virtual screen in pixels. These values are used to
 209      * limit the maximum size of the window.
 210      */
 211     private static volatile int maxWindowWidthInPixels = -1;
 212     private static volatile int maxWindowHeightInPixels = -1;
 213 
 214     private static XMouseInfoPeer xPeer;
 215 
 216     /**
 217      * Should we check "_NET_WM_STRUT/_NET_WM_STRUT_PARTIAL" during insets
 218      * calculation.
 219      */
 220     private static Boolean checkSTRUT;
 221 
 222     static {
 223         initSecurityWarning();
 224         if (GraphicsEnvironment.isHeadless()) {
 225             localEnv = null;
 226             device = null;
 227             display = 0;
 228         } else {
 229             localEnv = (X11GraphicsEnvironment) GraphicsEnvironment
 230                 .getLocalGraphicsEnvironment();
 231             device = (X11GraphicsDevice) localEnv.getDefaultScreenDevice();
 232             display = device.getDisplay();
 233             setupModifierMap();
 234             initIDs();
 235             setBackingStoreType();
 236         }
 237     }
 238 
 239     /*
 240      * Return (potentially) platform specific display timeout for the
 241      * tray icon


 844      *
 845      *         //<-x1,y1///////
 846      *         //            // ////////////////
 847      *         //  SCREEN1   // // SCREEN2    //
 848      *         // ********** // //     x2,y2->//
 849      *         //////////////// //            //
 850      *                          ////////////////
 851      *
 852      * When two screens overlap and the first contains a dock(*****), then
 853      * _NET_WORKAREA may start at point x1,y1 and end at point x2,y2.
 854      */
 855     @Override
 856     public Insets getScreenInsets(final GraphicsConfiguration gc) {
 857         GraphicsDevice gd = gc.getDevice();
 858         XNETProtocol np = XWM.getWM().getNETProtocol();
 859         if (np == null || !(gd instanceof X11GraphicsDevice) || !np.active()) {
 860             return super.getScreenInsets(gc);
 861         }
 862 
 863         XToolkit.awtLock();
 864         try
 865         {
 866             X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
 867                     GraphicsEnvironment.getLocalGraphicsEnvironment();
 868             X11GraphicsConfig x11gc = (X11GraphicsConfig) gc;
 869             long root = XlibUtil.getRootWindow(x11gc.getDevice().getScreen());
 870             int scale = x11gc.getScale();
 871             if (x11ge.runningXinerama() && checkSTRUT()) {
 872                 // implementation based on _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL
 873                 Rectangle rootBounds = XlibUtil.getWindowGeometry(root, scale);
 874                 Insets insets = getScreenInsetsManually(root, rootBounds,
 875                                                         gc.getBounds(), scale);
 876                 if ((insets.left | insets.top | insets.bottom | insets.right) != 0
 877                         || rootBounds == null) {
 878                     return insets;
 879                 }
 880             }
 881             Rectangle workArea = XToolkit.getWorkArea(root, scale);
 882             Rectangle screen = gc.getBounds();
 883             if (workArea != null && screen.contains(workArea.getLocation())) {
 884                 workArea = workArea.intersection(screen);
 885                 int top = workArea.y - screen.y;
 886                 int left = workArea.x - screen.x;
 887                 int bottom = screen.height - workArea.height - top;
 888                 int right = screen.width - workArea.width - left;
 889                 return new Insets(top, left, bottom, right);
 890             }
 891             // Note that it is better to return zeros than inadequate values
 892             return new Insets(0, 0, 0, 0);
 893         }
 894         finally
 895         {
 896             XToolkit.awtUnlock();
 897         }
 898     }
 899 
 900     /**
 901      * Returns the value of "sun.awt.X11.checkSTRUT" property. Default value is
 902      * {@code false}.
 903      */
 904     private static boolean checkSTRUT() {
 905         if (checkSTRUT == null) {
 906             checkSTRUT = AccessController.doPrivileged(
 907                     new GetBooleanAction("sun.awt.X11.checkSTRUT"));
 908         }
 909         return checkSTRUT;
 910     }
 911 
 912     /*
 913      * Manual calculation of screen insets: get all the windows with
 914      * _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these
 915      * hints' values to screen insets.
 916      *
 917      * This method should be called under XToolkit.awtLock()
 918      *
 919      * This method is unused by default because of two reasons:
 920      *  - Iteration over windows may be extremely slow, and execution of
 921      *    getScreenInsets() can be x100 slower than in one monitor config.
 922      *  - _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL are hints for the applications.
 923      *    WM should take into account these hints when "_NET_WORKAREA" is
 924      *    calculated, but the system panels do not necessarily contain these
 925      *    hints(Gnome 3 for example).
 926      */
 927     private Insets getScreenInsetsManually(long root, Rectangle rootBounds,
 928                                            Rectangle screenBounds, int scale)
 929     {
 930         /*
 931          * During the manual calculation of screen insets we iterate
 932          * all the X windows hierarchy starting from root window. This
 933          * constant is the max level inspected in this hierarchy.
 934          * 3 is a heuristic value: I suppose any the toolbar-like
 935          * window is a child of either root or desktop window.
 936          */
 937         final int MAX_NESTED_LEVEL = 3;
 938 
 939         XAtom XA_NET_WM_STRUT = XAtom.get("_NET_WM_STRUT");
 940         XAtom XA_NET_WM_STRUT_PARTIAL = XAtom.get("_NET_WM_STRUT_PARTIAL");
 941 
 942         Insets insets = new Insets(0, 0, 0, 0);
 943 
 944         java.util.List<Object> search = new LinkedList<>();
 945         search.add(root);
 946         search.add(0);
 947         while (!search.isEmpty())
 948         {
 949             long window = (Long)search.remove(0);
 950             int windowLevel = (Integer)search.remove(0);
 951 
 952             /*
 953              * Note that most of the modern window managers unmap
 954              * application window if it is iconified. Thus, any
 955              * _NET_WM_STRUT[_PARTIAL] hints for iconified windows
 956              * are not included to the screen insets.
 957              */
 958             if (XlibUtil.getWindowMapState(window) == XConstants.IsUnmapped)
 959             {
 960                 continue;
 961             }
 962 
 963             long native_ptr = Native.allocateLongArray(4);
 964             try
 965             {
 966                 // first, check if _NET_WM_STRUT or _NET_WM_STRUT_PARTIAL are present
 967                 // if both are set on the window, _NET_WM_STRUT_PARTIAL is used (see _NET spec)
 968                 boolean strutPresent = XA_NET_WM_STRUT_PARTIAL.getAtomData(window, XAtom.XA_CARDINAL, native_ptr, 4);
 969                 if (!strutPresent)
 970                 {
 971                     strutPresent = XA_NET_WM_STRUT.getAtomData(window, XAtom.XA_CARDINAL, native_ptr, 4);
 972                 }
 973                 if (strutPresent)
 974                 {
 975                     // second, verify that window is located on the proper screen
 976                     Rectangle windowBounds = XlibUtil.getWindowGeometry(window,
 977                                                                         scale);
 978                     if (windowLevel > 1)
 979                     {
 980                         windowBounds = XlibUtil.translateCoordinates(window, root,
 981                                                                      windowBounds,
 982                                                                      scale);
 983                     }
 984                     // if _NET_WM_STRUT_PARTIAL is present, we should use its values to detect
 985                     // if the struts area intersects with screenBounds, however some window
 986                     // managers don't set this hint correctly, so we just get intersection with windowBounds
 987                     if (windowBounds != null && windowBounds.intersects(screenBounds))
 988                     {
 989                         int left = scaleDown((int)Native.getLong(native_ptr, 0), scale);
 990                         int right = scaleDown((int)Native.getLong(native_ptr, 1), scale);
 991                         int top = scaleDown((int)Native.getLong(native_ptr, 2), scale);
 992                         int bottom = scaleDown((int)Native.getLong(native_ptr, 3), scale);
 993 
 994                         /*
 995                          * struts could be relative to root window bounds, so
 996                          * make them relative to the screen bounds in this case
 997                          */
 998                         left = rootBounds.x + left > screenBounds.x ?
 999                                 rootBounds.x + left - screenBounds.x : 0;
1000                         right = rootBounds.x + rootBounds.width - right <
1001                                 screenBounds.x + screenBounds.width ?
1002                                 screenBounds.x + screenBounds.width -
1003                                 (rootBounds.x + rootBounds.width - right) : 0;
1004                         top = rootBounds.y + top > screenBounds.y ?
1005                                 rootBounds.y + top - screenBounds.y : 0;
1006                         bottom = rootBounds.y + rootBounds.height - bottom <
1007                                 screenBounds.y + screenBounds.height ?
1008                                 screenBounds.y + screenBounds.height -
1009                                 (rootBounds.y + rootBounds.height - bottom) : 0;
1010 
1011                         insets.left = Math.max(left, insets.left);
1012                         insets.right = Math.max(right, insets.right);
1013                         insets.top = Math.max(top, insets.top);
1014                         insets.bottom = Math.max(bottom, insets.bottom);
1015                     }
1016                 }
1017             }
1018             finally
1019             {
1020                 XlibWrapper.unsafe.freeMemory(native_ptr);
1021             }
1022 
1023             if (windowLevel < MAX_NESTED_LEVEL)
1024             {
1025                 Set<Long> children = XlibUtil.getChildWindows(window);
1026                 for (long child : children)
1027                 {
1028                     search.add(child);
1029                     search.add(windowLevel + 1);
1030                 }
1031             }
1032         }
1033 
1034         return insets;
1035     }
1036 
1037     /*
1038      * The current implementation of disabling background erasing for
1039      * canvases is that we don't set any native background color
1040      * (with XSetWindowBackground) for the canvas window. However,
1041      * this color is set in the peer constructor - see
1042      * XWindow.postInit() for details. That's why this method from
1043      * SunToolkit is not overridden in XToolkit: it's too late to
1044      * disable background erasing :(
1045      */
1046     /*
1047     @Override
1048     public void disableBackgroundErase(Canvas canvas) {
1049         XCanvasPeer peer = (XCanvasPeer)canvas.getPeer();
1050         if (peer == null) {
1051             throw new IllegalStateException("Canvas must have a valid peer");
1052         }
1053         peer.disableBackgroundErase();
1054     }




 104 import java.awt.peer.RobotPeer;
 105 import java.awt.peer.ScrollPanePeer;
 106 import java.awt.peer.ScrollbarPeer;
 107 import java.awt.peer.SystemTrayPeer;
 108 import java.awt.peer.TaskbarPeer;
 109 import java.awt.peer.TextAreaPeer;
 110 import java.awt.peer.TextFieldPeer;
 111 import java.awt.peer.TrayIconPeer;
 112 import java.awt.peer.WindowPeer;
 113 import java.beans.PropertyChangeListener;
 114 import java.security.AccessController;
 115 import java.security.PrivilegedAction;
 116 import java.util.ArrayList;
 117 import java.util.Collection;
 118 import java.util.HashMap;
 119 import java.util.Iterator;
 120 import java.util.LinkedList;
 121 import java.util.Map;
 122 import java.util.NoSuchElementException;
 123 import java.util.Properties;

 124 import java.util.SortedMap;
 125 import java.util.TreeMap;
 126 import java.util.Vector;
 127 
 128 import javax.swing.LookAndFeel;
 129 import javax.swing.UIDefaults;
 130 
 131 import sun.awt.AWTAccessor;
 132 import sun.awt.AWTPermissions;
 133 import sun.awt.AppContext;
 134 import sun.awt.DisplayChangedListener;
 135 import sun.awt.LightweightFrame;
 136 import sun.awt.SunToolkit;
 137 import sun.awt.UNIXToolkit;
 138 import sun.awt.X11GraphicsConfig;
 139 import sun.awt.X11GraphicsDevice;
 140 import sun.awt.X11GraphicsEnvironment;
 141 import sun.awt.XSettings;
 142 import sun.awt.datatransfer.DataTransferer;
 143 import sun.awt.util.PerformanceLogger;


 195     static int arrowCursor;
 196     static TreeMap<Long, XBaseWindow> winMap = new TreeMap<>();
 197     static HashMap<Object, Object> specialPeerMap = new HashMap<>();
 198     static HashMap<Long, Collection<XEventDispatcher>> winToDispatcher = new HashMap<>();
 199     static UIDefaults uidefaults;
 200     static final X11GraphicsEnvironment localEnv;
 201     private static final X11GraphicsDevice device;
 202     private static final long display;
 203     static int awt_multiclick_time;
 204     static boolean securityWarningEnabled;
 205 
 206     /**
 207      * Dimensions of default virtual screen in pixels. These values are used to
 208      * limit the maximum size of the window.
 209      */
 210     private static volatile int maxWindowWidthInPixels = -1;
 211     private static volatile int maxWindowHeightInPixels = -1;
 212 
 213     private static XMouseInfoPeer xPeer;
 214 






 215     static {
 216         initSecurityWarning();
 217         if (GraphicsEnvironment.isHeadless()) {
 218             localEnv = null;
 219             device = null;
 220             display = 0;
 221         } else {
 222             localEnv = (X11GraphicsEnvironment) GraphicsEnvironment
 223                 .getLocalGraphicsEnvironment();
 224             device = (X11GraphicsDevice) localEnv.getDefaultScreenDevice();
 225             display = device.getDisplay();
 226             setupModifierMap();
 227             initIDs();
 228             setBackingStoreType();
 229         }
 230     }
 231 
 232     /*
 233      * Return (potentially) platform specific display timeout for the
 234      * tray icon


 837      *
 838      *         //<-x1,y1///////
 839      *         //            // ////////////////
 840      *         //  SCREEN1   // // SCREEN2    //
 841      *         // ********** // //     x2,y2->//
 842      *         //////////////// //            //
 843      *                          ////////////////
 844      *
 845      * When two screens overlap and the first contains a dock(*****), then
 846      * _NET_WORKAREA may start at point x1,y1 and end at point x2,y2.
 847      */
 848     @Override
 849     public Insets getScreenInsets(final GraphicsConfiguration gc) {
 850         GraphicsDevice gd = gc.getDevice();
 851         XNETProtocol np = XWM.getWM().getNETProtocol();
 852         if (np == null || !(gd instanceof X11GraphicsDevice) || !np.active()) {
 853             return super.getScreenInsets(gc);
 854         }
 855 
 856         XToolkit.awtLock();
 857         try {
 858             X11GraphicsDevice x11gd = (X11GraphicsDevice) gd;
 859             long root = XlibUtil.getRootWindow(x11gd.getScreen());
 860             Rectangle workArea = getWorkArea(root, x11gd.getScaleFactor());














 861             Rectangle screen = gc.getBounds();
 862             if (workArea != null && screen.contains(workArea.getLocation())) {
 863                 workArea = workArea.intersection(screen);
 864                 int top = workArea.y - screen.y;
 865                 int left = workArea.x - screen.x;
 866                 int bottom = screen.height - workArea.height - top;
 867                 int right = screen.width - workArea.width - left;
 868                 return new Insets(top, left, bottom, right);
 869             }
 870             // Note that it is better to return zeros than inadequate values
 871             return new Insets(0, 0, 0, 0);
 872         } finally {


 873             XToolkit.awtUnlock();
 874         }









































































































































 875     }
 876 
 877     /*
 878      * The current implementation of disabling background erasing for
 879      * canvases is that we don't set any native background color
 880      * (with XSetWindowBackground) for the canvas window. However,
 881      * this color is set in the peer constructor - see
 882      * XWindow.postInit() for details. That's why this method from
 883      * SunToolkit is not overridden in XToolkit: it's too late to
 884      * disable background erasing :(
 885      */
 886     /*
 887     @Override
 888     public void disableBackgroundErase(Canvas canvas) {
 889         XCanvasPeer peer = (XCanvasPeer)canvas.getPeer();
 890         if (peer == null) {
 891             throw new IllegalStateException("Canvas must have a valid peer");
 892         }
 893         peer.disableBackgroundErase();
 894     }


< prev index next >