1 /*
2 * Copyright (c) 2011, 2013, 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
72
73 private GraphicsDevice graphicsDevice;
74 private GraphicsConfiguration graphicsConfig;
75
76 private SurfaceData surfaceData;
77 private final Object surfaceDataLock = new Object();
78
79 private int backBufferCount;
80 private BufferCapabilities backBufferCaps;
81
82 // The back buffer is used for two purposes:
83 // 1. To render all the lightweight peers
84 // 2. To provide user with a BufferStrategy
85 // Need to check if a single back buffer can be used for both
86 // TODO: VolatileImage
87 // private VolatileImage backBuffer;
88 private volatile BufferedImage backBuffer;
89
90 private volatile int windowState = Frame.NORMAL;
91
92 // A peer where the last mouse event came to. Used to generate
93 // MOUSE_ENTERED/EXITED notifications and by cursor manager to
94 // find the component under cursor
95 private static volatile LWComponentPeer lastMouseEventPeer = null;
96
97 // Peers where all dragged/released events should come to,
98 // depending on what mouse button is being dragged according to Cocoa
99 private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3];
100
101 // A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events
102 // on MOUSE_RELEASE. Click events are only generated if there were no drag
103 // events between MOUSE_PRESSED and MOUSE_RELEASED for particular button
104 private static int mouseClickButtons = 0;
105
106 private volatile boolean isOpaque = true;
107
108 private static final Font DEFAULT_FONT = new Font("Lucida Grande", Font.PLAIN, 13);
109
110 private static LWWindowPeer grabbingWindow;
111
112 private volatile boolean skipNextFocusChange;
113
114 private static final Color nonOpaqueBackground = new Color(0, 0, 0, 0);
115
756 }
757 }
758
759 // ---- EVENTS ---- //
760
761 /*
762 * Called by the delegate to dispatch the event to Java. Event
763 * coordinates are relative to non-client window are, i.e. the top-left
764 * point of the client area is (insets.top, insets.left).
765 */
766 @Override
767 public void notifyMouseEvent(int id, long when, int button,
768 int x, int y, int screenX, int screenY,
769 int modifiers, int clickCount, boolean popupTrigger,
770 byte[] bdata)
771 {
772 // TODO: fill "bdata" member of AWTEvent
773 Rectangle r = getBounds();
774 // findPeerAt() expects parent coordinates
775 LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
776 LWWindowPeer lastWindowPeer =
777 (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
778 LWWindowPeer curWindowPeer =
779 (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null;
780
781 if (id == MouseEvent.MOUSE_EXITED) {
782 // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched
783 // to a peer from another window. So we must first check if this peer is
784 // the same as lastWindowPeer
785 if (lastWindowPeer == this) {
786 if (isEnabled()) {
787 Point lp = lastMouseEventPeer.windowToLocal(x, y,
788 lastWindowPeer);
789 Component target = lastMouseEventPeer.getTarget();
790 postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED,
791 when, modifiers, lp,
792 screenX, screenY, clickCount, popupTrigger, button);
793 }
794 lastMouseEventPeer = null;
795 }
796 } else {
797 if (targetPeer != lastMouseEventPeer) {
798 // lastMouseEventPeer may be null if mouse was out of Java windows
799 if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
800 // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
801 // later), in which case lastWindowPeer is another window
802 if (lastWindowPeer != this) {
803 Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
804 // Additionally translate from this to lastWindowPeer coordinates
805 Rectangle lr = lastWindowPeer.getBounds();
806 oldp.x += r.x - lr.x;
807 oldp.y += r.y - lr.y;
808 Component target = lastMouseEventPeer.getTarget();
809 postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED,
810 when, modifiers, oldp,
811 screenX, screenY, clickCount, popupTrigger, button);
812 } else {
813 Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
814 Component target = lastMouseEventPeer.getTarget();
815 postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED,
816 when, modifiers, oldp,
817 screenX, screenY, clickCount, popupTrigger, button);
818 }
819 }
820 lastMouseEventPeer = targetPeer;
821 if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
822 Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
823 Component target = targetPeer.getTarget();
824 postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED,
825 when, modifiers, newp,
826 screenX, screenY, clickCount, popupTrigger, button);
827 }
828 }
829 // TODO: fill "bdata" member of AWTEvent
830
831 int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
832 int otherButtonsPressed = modifiers & ~eventButtonMask;
833
834 // For pressed/dragged/released events OS X treats other
835 // mouse buttons as if they were BUTTON2, so we do the same
836 int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1;
837
838 // MOUSE_ENTERED/EXITED are generated for the components strictly under
839 // mouse even when dragging. That's why we first update lastMouseEventPeer
840 // based on initial targetPeer value and only then recalculate targetPeer
841 // for MOUSE_DRAGGED/RELEASED events
842 if (id == MouseEvent.MOUSE_PRESSED) {
843
844 // Ungrab only if this window is not an owned window of the grabbing one.
845 if (!isGrabbing() && grabbingWindow != null &&
846 grabbingWindow != getOwnerFrameDialog(this))
847 {
848 grabbingWindow.ungrab();
858 // Cocoa dragged event has the information about which mouse
859 // button is being dragged. Use it to determine the peer that
860 // should receive the dragged event.
861 targetPeer = mouseDownTarget[targetIdx];
862 mouseClickButtons &= ~modifiers;
863 } else if (id == MouseEvent.MOUSE_RELEASED) {
864 // TODO: currently, mouse released event goes to the same component
865 // that received corresponding mouse pressed event. For most cases,
866 // it's OK, however, we need to make sure that our behavior is consistent
867 // with 1.6 for cases where component in question have been
868 // hidden/removed in between of mouse pressed/released events.
869 targetPeer = mouseDownTarget[targetIdx];
870
871 if ((modifiers & eventButtonMask) == 0) {
872 mouseDownTarget[targetIdx] = null;
873 }
874
875 // mouseClickButtons is updated below, after MOUSE_CLICK is sent
876 }
877
878 // check if we receive mouseEvent from outside the window's bounds
879 // it can be either mouseDragged or mouseReleased
880 if (curWindowPeer == null) {
881 //TODO This can happen if this window is invisible. this is correct behavior in this case?
882 curWindowPeer = this;
883 }
884 if (targetPeer == null) {
885 //TODO This can happen if this window is invisible. this is correct behavior in this case?
886 targetPeer = this;
887 }
888
889
890 Point lp = targetPeer.windowToLocal(x, y, curWindowPeer);
891 if (targetPeer.isEnabled()) {
892 if (id == MouseEvent.MOUSE_ENTERED || id == MouseEvent.MOUSE_EXITED) {
893 postMouseEnteredExitedEvent(targetPeer.getTarget(), id,
894 when, modifiers, lp, screenX, screenY,
895 clickCount, popupTrigger, button);
896
897 } else {
898 MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
899 when, modifiers, lp.x, lp.y,
900 screenX, screenY, clickCount,
901 popupTrigger, button);
902 postEvent(event);
903 }
904 }
905
906 if (id == MouseEvent.MOUSE_RELEASED) {
907 if ((mouseClickButtons & eventButtonMask) != 0
908 && targetPeer.isEnabled()) {
909 postEvent(new MouseEvent(targetPeer.getTarget(),
910 MouseEvent.MOUSE_CLICKED,
911 when, modifiers,
912 lp.x, lp.y, screenX, screenY,
913 clickCount, popupTrigger, button));
914 }
915 mouseClickButtons &= ~eventButtonMask;
916 }
917 }
918 notifyUpdateCursor();
919 }
920
921 private void postMouseEnteredExitedEvent(
922 Component target, int id, long when, int modifiers,
923 Point loc, int xAbs, int yAbs,
924 int clickCount, boolean popupTrigger, int button) {
925
926 updateSecurityWarningVisibility();
927
928 postEvent(new MouseEvent(target, id, when, modifiers, loc.x, loc.y,
929 xAbs, yAbs, clickCount, popupTrigger, button));
930 }
931
932 @Override
933 public void notifyMouseWheelEvent(long when, int x, int y, int modifiers,
934 int scrollType, int scrollAmount,
935 int wheelRotation, double preciseWheelRotation,
936 byte[] bdata)
937 {
938 // TODO: could we just use the last mouse event target here?
939 Rectangle r = getBounds();
940 // findPeerAt() expects parent coordinates
1181 }
1182
1183 /**
1184 * Request the window insets from the delegate and compares it with the
1185 * current one. This method is mostly called by the delegate, e.g. when the
1186 * window state is changed and insets should be recalculated.
1187 * <p/>
1188 * This method may be called on the toolkit thread.
1189 */
1190 public final boolean updateInsets(final Insets newInsets) {
1191 synchronized (getStateLock()) {
1192 if (insets.equals(newInsets)) {
1193 return false;
1194 }
1195 insets = newInsets;
1196 }
1197 return true;
1198 }
1199
1200 public static LWWindowPeer getWindowUnderCursor() {
1201 return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
1202 }
1203
1204 public static LWComponentPeer<?, ?> getPeerUnderCursor() {
1205 return lastMouseEventPeer;
1206 }
1207
1208 /*
1209 * Requests platform to set native focus on a frame/dialog.
1210 * In case of a simple window, triggers appropriate java focus change.
1211 */
1212 public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
1213 if (focusLog.isLoggable(PlatformLogger.FINE)) {
1214 focusLog.fine("requesting native focus to " + this);
1215 }
1216
1217 if (!focusAllowedFor()) {
1218 focusLog.fine("focus is not allowed");
1219 return false;
1220 }
1221
1222 if (platformWindow.rejectFocusRequest(cause)) {
1223 return false;
1224 }
1225
|
1 /*
2 * Copyright (c) 2011, 2014, 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
72
73 private GraphicsDevice graphicsDevice;
74 private GraphicsConfiguration graphicsConfig;
75
76 private SurfaceData surfaceData;
77 private final Object surfaceDataLock = new Object();
78
79 private int backBufferCount;
80 private BufferCapabilities backBufferCaps;
81
82 // The back buffer is used for two purposes:
83 // 1. To render all the lightweight peers
84 // 2. To provide user with a BufferStrategy
85 // Need to check if a single back buffer can be used for both
86 // TODO: VolatileImage
87 // private VolatileImage backBuffer;
88 private volatile BufferedImage backBuffer;
89
90 private volatile int windowState = Frame.NORMAL;
91
92 // check that the mouse is over the window
93 private volatile boolean isMouseOver = false;
94 // A peer where the last mouse event came to. Used by cursor manager to
95 // find the component under cursor
96 private static volatile LWComponentPeer lastCommonMouseEventPeer = null;
97
98 // A peer where the last mouse event came to. Used to generate
99 // MOUSE_ENTERED/EXITED notifications
100 private volatile LWComponentPeer lastMouseEventPeer;
101
102 // Peers where all dragged/released events should come to,
103 // depending on what mouse button is being dragged according to Cocoa
104 private static LWComponentPeer mouseDownTarget[] = new LWComponentPeer[3];
105
106 // A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events
107 // on MOUSE_RELEASE. Click events are only generated if there were no drag
108 // events between MOUSE_PRESSED and MOUSE_RELEASED for particular button
109 private static int mouseClickButtons = 0;
110
111 private volatile boolean isOpaque = true;
112
113 private static final Font DEFAULT_FONT = new Font("Lucida Grande", Font.PLAIN, 13);
114
115 private static LWWindowPeer grabbingWindow;
116
117 private volatile boolean skipNextFocusChange;
118
119 private static final Color nonOpaqueBackground = new Color(0, 0, 0, 0);
120
761 }
762 }
763
764 // ---- EVENTS ---- //
765
766 /*
767 * Called by the delegate to dispatch the event to Java. Event
768 * coordinates are relative to non-client window are, i.e. the top-left
769 * point of the client area is (insets.top, insets.left).
770 */
771 @Override
772 public void notifyMouseEvent(int id, long when, int button,
773 int x, int y, int screenX, int screenY,
774 int modifiers, int clickCount, boolean popupTrigger,
775 byte[] bdata)
776 {
777 // TODO: fill "bdata" member of AWTEvent
778 Rectangle r = getBounds();
779 // findPeerAt() expects parent coordinates
780 LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
781
782 if (id == MouseEvent.MOUSE_EXITED) {
783 isMouseOver = false;
784 if (lastMouseEventPeer != null) {
785 if (lastMouseEventPeer.isEnabled()) {
786 Point lp = lastMouseEventPeer.windowToLocal(x, y,
787 this);
788 Component target = lastMouseEventPeer.getTarget();
789 postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED,
790 when, modifiers, lp,
791 screenX, screenY, clickCount, popupTrigger, button);
792 }
793
794 // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
795 // to a peer from another window. So we must first check if this peer is
796 // the same as lastWindowPeer
797 if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) {
798 lastCommonMouseEventPeer = null;
799 }
800 lastMouseEventPeer = null;
801 }
802 } else if (id == MouseEvent.MOUSE_ENTERED) {
803 isMouseOver = true;
804 if (targetPeer != null) {
805 if (targetPeer.isEnabled()) {
806 Point lp = targetPeer.windowToLocal(x, y, this);
807 Component target = targetPeer.getTarget();
808 postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, when, modifiers, lp,
809 screenX, screenY, clickCount, popupTrigger, button);
810 }
811 lastCommonMouseEventPeer = targetPeer;
812 lastMouseEventPeer = targetPeer;
813 }
814 } else {
815 PlatformWindow topmostPlatformWindow =
816 platformWindow.getTopmostPlatformWindowUnderMouse();
817
818 LWWindowPeer topmostWindowPeer =
819 topmostPlatformWindow != null ? topmostPlatformWindow.getPeer() : null;
820
821 // topmostWindowPeer == null condition is added for the backword
822 // compatibility with applets. It can be removed when the
823 // getTopmostPlatformWindowUnderMouse() method will be properly
824 // implemented i CPlatformEmbeddedFrame class
825 if (topmostWindowPeer == this || topmostWindowPeer == null) {
826 generateMouseEnterExitEventsForComponents(when, button, x, y,
827 screenX, screenY, modifiers, clickCount, popupTrigger,
828 targetPeer);
829 } else {
830 LWComponentPeer topmostTargetPeer =
831 topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null;
832 topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y,
833 screenX, screenY, modifiers, clickCount, popupTrigger,
834 topmostTargetPeer);
835 }
836
837 // TODO: fill "bdata" member of AWTEvent
838
839 int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
840 int otherButtonsPressed = modifiers & ~eventButtonMask;
841
842 // For pressed/dragged/released events OS X treats other
843 // mouse buttons as if they were BUTTON2, so we do the same
844 int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1;
845
846 // MOUSE_ENTERED/EXITED are generated for the components strictly under
847 // mouse even when dragging. That's why we first update lastMouseEventPeer
848 // based on initial targetPeer value and only then recalculate targetPeer
849 // for MOUSE_DRAGGED/RELEASED events
850 if (id == MouseEvent.MOUSE_PRESSED) {
851
852 // Ungrab only if this window is not an owned window of the grabbing one.
853 if (!isGrabbing() && grabbingWindow != null &&
854 grabbingWindow != getOwnerFrameDialog(this))
855 {
856 grabbingWindow.ungrab();
866 // Cocoa dragged event has the information about which mouse
867 // button is being dragged. Use it to determine the peer that
868 // should receive the dragged event.
869 targetPeer = mouseDownTarget[targetIdx];
870 mouseClickButtons &= ~modifiers;
871 } else if (id == MouseEvent.MOUSE_RELEASED) {
872 // TODO: currently, mouse released event goes to the same component
873 // that received corresponding mouse pressed event. For most cases,
874 // it's OK, however, we need to make sure that our behavior is consistent
875 // with 1.6 for cases where component in question have been
876 // hidden/removed in between of mouse pressed/released events.
877 targetPeer = mouseDownTarget[targetIdx];
878
879 if ((modifiers & eventButtonMask) == 0) {
880 mouseDownTarget[targetIdx] = null;
881 }
882
883 // mouseClickButtons is updated below, after MOUSE_CLICK is sent
884 }
885
886 if (targetPeer == null) {
887 //TODO This can happen if this window is invisible. this is correct behavior in this case?
888 targetPeer = this;
889 }
890
891
892 Point lp = targetPeer.windowToLocal(x, y, this);
893 if (targetPeer.isEnabled()) {
894 if (id == MouseEvent.MOUSE_ENTERED || id == MouseEvent.MOUSE_EXITED) {
895 postMouseEnteredExitedEvent(targetPeer.getTarget(), id,
896 when, modifiers, lp, screenX, screenY,
897 clickCount, popupTrigger, button);
898
899 } else {
900 MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
901 when, modifiers, lp.x, lp.y,
902 screenX, screenY, clickCount,
903 popupTrigger, button);
904 postEvent(event);
905 }
906 }
907
908 if (id == MouseEvent.MOUSE_RELEASED) {
909 if ((mouseClickButtons & eventButtonMask) != 0
910 && targetPeer.isEnabled()) {
911 postEvent(new MouseEvent(targetPeer.getTarget(),
912 MouseEvent.MOUSE_CLICKED,
913 when, modifiers,
914 lp.x, lp.y, screenX, screenY,
915 clickCount, popupTrigger, button));
916 }
917 mouseClickButtons &= ~eventButtonMask;
918 }
919 }
920 notifyUpdateCursor();
921 }
922
923 private void generateMouseEnterExitEventsForComponents(long when,
924 int button, int x, int y, int screenX, int screenY,
925 int modifiers, int clickCount, boolean popupTriger,
926 LWComponentPeer targetPeer) {
927 if (!isMouseOver || targetPeer == lastMouseEventPeer) {
928 return;
929 }
930
931 // Generate Mouse Exit for components
932 if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
933 Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
934 Component target = lastMouseEventPeer.getTarget();
935 postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, when, modifiers,
936 oldp, screenX, screenY, clickCount, popupTriger, button);
937 }
938 lastCommonMouseEventPeer = targetPeer;
939 lastMouseEventPeer = targetPeer;
940
941 // Genrate Mouse Enter for Componetns
942 if (targetPeer != null && targetPeer.isEnabled()) {
943 Point newp = targetPeer.windowToLocal(x, y, this);
944 Component target = targetPeer.getTarget();
945 postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, when, modifiers,
946 newp, screenX, screenY, clickCount, popupTriger, button);
947 }
948 }
949
950 private void postMouseEnteredExitedEvent(
951 Component target, int id, long when, int modifiers,
952 Point loc, int xAbs, int yAbs,
953 int clickCount, boolean popupTrigger, int button) {
954
955 updateSecurityWarningVisibility();
956
957 postEvent(new MouseEvent(target, id, when, modifiers, loc.x, loc.y,
958 xAbs, yAbs, clickCount, popupTrigger, button));
959 }
960
961 @Override
962 public void notifyMouseWheelEvent(long when, int x, int y, int modifiers,
963 int scrollType, int scrollAmount,
964 int wheelRotation, double preciseWheelRotation,
965 byte[] bdata)
966 {
967 // TODO: could we just use the last mouse event target here?
968 Rectangle r = getBounds();
969 // findPeerAt() expects parent coordinates
1210 }
1211
1212 /**
1213 * Request the window insets from the delegate and compares it with the
1214 * current one. This method is mostly called by the delegate, e.g. when the
1215 * window state is changed and insets should be recalculated.
1216 * <p/>
1217 * This method may be called on the toolkit thread.
1218 */
1219 public final boolean updateInsets(final Insets newInsets) {
1220 synchronized (getStateLock()) {
1221 if (insets.equals(newInsets)) {
1222 return false;
1223 }
1224 insets = newInsets;
1225 }
1226 return true;
1227 }
1228
1229 public static LWWindowPeer getWindowUnderCursor() {
1230 return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null;
1231 }
1232
1233 public static LWComponentPeer<?, ?> getPeerUnderCursor() {
1234 return lastCommonMouseEventPeer;
1235 }
1236
1237 /*
1238 * Requests platform to set native focus on a frame/dialog.
1239 * In case of a simple window, triggers appropriate java focus change.
1240 */
1241 public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
1242 if (focusLog.isLoggable(PlatformLogger.FINE)) {
1243 focusLog.fine("requesting native focus to " + this);
1244 }
1245
1246 if (!focusAllowedFor()) {
1247 focusLog.fine("focus is not allowed");
1248 return false;
1249 }
1250
1251 if (platformWindow.rejectFocusRequest(cause)) {
1252 return false;
1253 }
1254
|