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 }
|