< prev index next >

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

Print this page


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


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






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


 809                 int rootX = (int)Native.getLong(native_ptr, 0);
 810                 int rootY = (int)Native.getLong(native_ptr, 1);
 811                 int rootWidth = (int)Native.getLong(native_ptr, 2);
 812                 int rootHeight = (int)Native.getLong(native_ptr, 3);
 813 
 814                 return new Rectangle(scaleDown(rootX, scale),
 815                                      scaleDown(rootY, scale),
 816                                      scaleDown(rootWidth, scale),
 817                                      scaleDown(rootHeight, scale));
 818             }
 819         }
 820         finally
 821         {
 822             XlibWrapper.unsafe.freeMemory(native_ptr);
 823         }
 824 
 825         return null;
 826     }
 827 
 828     /*
 829      * If we're running in non-Xinerama environment and the current
 830      * window manager supports _NET protocol then the screen insets
 831      * are calculated using _NET_WM_WORKAREA property of the root
 832      * window.
 833      * Otherwise, i. e. if Xinerama is on or _NET_WM_WORKAREA is
 834      * not set, we try to calculate the insets ourselves using
 835      * getScreenInsetsManually method.













 836      */
 837     @Override
 838     public Insets getScreenInsets(GraphicsConfiguration gc)
 839     {
 840         XNETProtocol netProto = XWM.getWM().getNETProtocol();
 841         if ((netProto == null) || !netProto.active())
 842         {
 843             return super.getScreenInsets(gc);
 844         }
 845 
 846         XToolkit.awtLock();
 847         try
 848         {
 849             X11GraphicsConfig x11gc = (X11GraphicsConfig)gc;
 850             X11GraphicsDevice x11gd = x11gc.getDevice();
 851             long root = XlibUtil.getRootWindow(x11gd.getScreen());
 852             int scale = x11gc.getScale();
 853             Rectangle rootBounds = XlibUtil.getWindowGeometry(root, scale);
 854 
 855             X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
 856                 GraphicsEnvironment.getLocalGraphicsEnvironment();
 857             if (!x11ge.runningXinerama())
 858             {
 859                 Insets screenInsets = getInsets(root, rootBounds, scale);
 860                 if (screenInsets != null) return screenInsets;
 861             }
 862 
 863             Insets insets = getScreenInsetsManually(root, rootBounds,
 864                     gc.getBounds(), scale);
 865             if ((insets.left | insets.top | insets.bottom | insets.right) == 0
 866                     && rootBounds != null ) {
 867                 root = XlibWrapper.RootWindow(XToolkit.getDisplay(),
 868                         x11gd.getScreen());
 869                 Insets screenInsets = getInsets(root, rootBounds, scale);
 870                 if (screenInsets != null) return screenInsets;
 871             }
 872             return insets;
 873         }














 874         finally
 875         {
 876             XToolkit.awtUnlock();
 877         }
 878     }
 879 
 880     private Insets getInsets(long root, Rectangle rootBounds, int scale) {
 881         Rectangle workArea = XToolkit.getWorkArea(root, scale);
 882         if (workArea == null) {
 883             return null;




 884         }
 885         return new Insets(workArea.y, workArea.x,
 886                 rootBounds.height - workArea.height - workArea.y,
 887                 rootBounds.width - workArea.width - workArea.x);
 888     }
 889 
 890     /*
 891      * Manual calculation of screen insets: get all the windows with
 892      * _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these
 893      * hints' values to screen insets.
 894      *
 895      * This method should be called under XToolkit.awtLock()








 896      */
 897     private Insets getScreenInsetsManually(long root, Rectangle rootBounds,
 898                                            Rectangle screenBounds, int scale)
 899     {
 900         /*
 901          * During the manual calculation of screen insets we iterate
 902          * all the X windows hierarchy starting from root window. This
 903          * constant is the max level inspected in this hierarchy.
 904          * 3 is a heuristic value: I suppose any the toolbar-like
 905          * window is a child of either root or desktop window.
 906          */
 907         final int MAX_NESTED_LEVEL = 3;
 908 
 909         XAtom XA_NET_WM_STRUT = XAtom.get("_NET_WM_STRUT");
 910         XAtom XA_NET_WM_STRUT_PARTIAL = XAtom.get("_NET_WM_STRUT_PARTIAL");
 911 
 912         Insets insets = new Insets(0, 0, 0, 0);
 913 
 914         java.util.List<Object> search = new LinkedList<>();
 915         search.add(root);


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


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


 815                 int rootX = (int)Native.getLong(native_ptr, 0);
 816                 int rootY = (int)Native.getLong(native_ptr, 1);
 817                 int rootWidth = (int)Native.getLong(native_ptr, 2);
 818                 int rootHeight = (int)Native.getLong(native_ptr, 3);
 819 
 820                 return new Rectangle(scaleDown(rootX, scale),
 821                                      scaleDown(rootY, scale),
 822                                      scaleDown(rootWidth, scale),
 823                                      scaleDown(rootHeight, scale));
 824             }
 825         }
 826         finally
 827         {
 828             XlibWrapper.unsafe.freeMemory(native_ptr);
 829         }
 830 
 831         return null;
 832     }
 833 
 834     /*
 835      * If the current window manager supports _NET protocol then the screen
 836      * insets are calculated using _NET_WORKAREA property of the root window.
 837      * <p>
 838      * Note that _NET_WORKAREA is a rectangular area and it does not work
 839      * well in the Xinerama mode.
 840      * <p>
 841      * We will trust the part of this rectangular area only if it starts at the
 842      * requested graphics configuration. Below is an example when the
 843      * _NET_WORKAREA intersects with the requested graphics configuration but
 844      * produce wrong result.
 845      *
 846      *         //<-x1,y1///////
 847      *         //            // ////////////////
 848      *         //  SCREEN1   // // SCREEN2    //
 849      *         // ********** // //     x2,y2->//
 850      *         //////////////// //            //
 851      *                          ////////////////
 852      *
 853      *  When two screens are overlap and the first contain a dock(*****), then
 854      *  _NET_WORKAREA may start at point x1,y1 and ends at point x2,y2.
 855      */
 856     @Override
 857     public Insets getScreenInsets(GraphicsConfiguration gc)
 858     {
 859         XNETProtocol netProto = XWM.getWM().getNETProtocol();
 860         if ((netProto == null) || !netProto.active())
 861         {
 862             return super.getScreenInsets(gc);
 863         }
 864 
 865         XToolkit.awtLock();
 866         try
 867         {






 868             X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
 869                     GraphicsEnvironment.getLocalGraphicsEnvironment();
 870             X11GraphicsConfig x11gc = (X11GraphicsConfig) gc;
 871             long root = XlibUtil.getRootWindow(x11gc.getDevice().getScreen());
 872             int scale = x11gc.getScale();
 873             if (x11ge.runningXinerama() && checkSTRUT()) {
 874                 // implementation based on _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL
 875                 Rectangle rootBounds = XlibUtil.getWindowGeometry(root, scale);
 876                 Insets insets = getScreenInsetsManually(root, rootBounds,
 877                                                         gc.getBounds(), scale);
 878                 if ((insets.left | insets.top | insets.bottom | insets.right) != 0
 879                         || rootBounds == null) {





 880                     return insets;
 881                 }
 882             }
 883             Rectangle workArea = XToolkit.getWorkArea(root, scale);
 884             Rectangle screen = gc.getBounds();
 885             if (workArea != null && screen.contains(workArea.getLocation())) {
 886                 workArea = workArea.intersection(screen);
 887                 int top = workArea.y - screen.y;
 888                 int left = workArea.x - screen.x;
 889                 int bottom = screen.height - workArea.height - top;
 890                 int right = screen.width - workArea.width - left;
 891                 return new Insets(top, left, bottom, right);
 892             }
 893             // Note that it is better to return zeros than inadequate values
 894             return new Insets(0, 0, 0, 0);
 895         }
 896         finally
 897         {
 898             XToolkit.awtUnlock();
 899         }
 900     }
 901 
 902     /**
 903      * Returns the value of "sun.awt.X11.checkSTRUT" property. Default value is
 904      * {@code false}.
 905      */
 906     private static boolean checkSTRUT() {
 907         if (checkSTRUT == null) {
 908             checkSTRUT = AccessController.doPrivileged(
 909                     new GetBooleanAction("sun.awt.X11.checkSTRUT"));
 910         }
 911         return checkSTRUT;


 912     }
 913 
 914     /*
 915      * Manual calculation of screen insets: get all the windows with
 916      * _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these
 917      * hints' values to screen insets.
 918      *
 919      * This method should be called under XToolkit.awtLock()
 920      *
 921      * This method is unused because of two reasons:
 922      *  - Iteration over windows may be extremely slow, and execution of
 923      *    getScreenInsets() can be x100 slower than in one monitor config.
 924      *  - _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL are hints for the applications.
 925      *    WM should take into account these hints when "_NET_WORKAREA" is
 926      *    calculated, but the system panels are not necessary contain these
 927      *    hints(Gnome 3 for example).
 928      */
 929     private Insets getScreenInsetsManually(long root, Rectangle rootBounds,
 930                                            Rectangle screenBounds, int scale)
 931     {
 932         /*
 933          * During the manual calculation of screen insets we iterate
 934          * all the X windows hierarchy starting from root window. This
 935          * constant is the max level inspected in this hierarchy.
 936          * 3 is a heuristic value: I suppose any the toolbar-like
 937          * window is a child of either root or desktop window.
 938          */
 939         final int MAX_NESTED_LEVEL = 3;
 940 
 941         XAtom XA_NET_WM_STRUT = XAtom.get("_NET_WM_STRUT");
 942         XAtom XA_NET_WM_STRUT_PARTIAL = XAtom.get("_NET_WM_STRUT_PARTIAL");
 943 
 944         Insets insets = new Insets(0, 0, 0, 0);
 945 
 946         java.util.List<Object> search = new LinkedList<>();
 947         search.add(root);


< prev index next >