729 // MouseDown in non-client area 730 @Override 731 public void notifyNCMouseDown() { 732 // Ungrab except for a click on a Dialog with the grabbing owner 733 if (grabbingWindow != null && 734 !grabbingWindow.isOneOfOwnersOf(this)) 735 { 736 grabbingWindow.ungrab(); 737 } 738 } 739 740 // ---- EVENTS ---- // 741 742 /* 743 * Called by the delegate to dispatch the event to Java. Event 744 * coordinates are relative to non-client window are, i.e. the top-left 745 * point of the client area is (insets.top, insets.left). 746 */ 747 @Override 748 public void notifyMouseEvent(int id, long when, int button, 749 int x, int y, int screenX, int screenY, 750 int modifiers, int clickCount, boolean popupTrigger, 751 byte[] bdata) 752 { 753 // TODO: fill "bdata" member of AWTEvent 754 Rectangle r = getBounds(); 755 // findPeerAt() expects parent coordinates 756 LWComponentPeer<?, ?> targetPeer = findPeerAt(r.x + x, r.y + y); 757 758 if (id == MouseEvent.MOUSE_EXITED) { 759 isMouseOver = false; 760 if (lastMouseEventPeer != null) { 761 if (lastMouseEventPeer.isEnabled()) { 762 Point lp = lastMouseEventPeer.windowToLocal(x, y, 763 this); 764 Component target = lastMouseEventPeer.getTarget(); 765 postMouseExitedEvent(target, when, modifiers, lp, 766 screenX, screenY, clickCount, popupTrigger, button); 767 } 768 769 // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched 770 // to a peer from another window. So we must first check if this peer is 771 // the same as lastWindowPeer 772 if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) { 773 lastCommonMouseEventPeer = null; 774 } 775 lastMouseEventPeer = null; 776 } 777 } else if(id == MouseEvent.MOUSE_ENTERED) { 778 isMouseOver = true; 779 if (targetPeer != null) { 780 if (targetPeer.isEnabled()) { 781 Point lp = targetPeer.windowToLocal(x, y, this); 782 Component target = targetPeer.getTarget(); 783 postMouseEnteredEvent(target, when, modifiers, lp, 784 screenX, screenY, clickCount, popupTrigger, button); 785 } 786 lastCommonMouseEventPeer = targetPeer; 787 lastMouseEventPeer = targetPeer; 788 } 789 } else { 790 PlatformWindow topmostPlatformWindow = LWToolkit.getLWToolkit().getPlatformWindowUnderMouse(); 791 792 LWWindowPeer topmostWindowPeer = 793 topmostPlatformWindow != null ? topmostPlatformWindow.getPeer() : null; 794 795 // topmostWindowPeer == null condition is added for the backward 796 // compatibility with applets. It can be removed when the 797 // getTopmostPlatformWindowUnderMouse() method will be properly 798 // implemented in CPlatformEmbeddedFrame class 799 if (topmostWindowPeer == this || topmostWindowPeer == null) { 800 generateMouseEnterExitEventsForComponents(when, button, x, y, 801 screenX, screenY, modifiers, clickCount, popupTrigger, 802 targetPeer); 803 } else { 804 LWComponentPeer<?, ?> topmostTargetPeer = topmostWindowPeer.findPeerAt(r.x + x, r.y + y); 805 topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y, 806 screenX, screenY, modifiers, clickCount, popupTrigger, 807 topmostTargetPeer); 808 } 809 810 // TODO: fill "bdata" member of AWTEvent 811 812 int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0; 813 int otherButtonsPressed = modifiers & ~eventButtonMask; 814 815 // For pressed/dragged/released events OS X treats other 816 // mouse buttons as if they were BUTTON2, so we do the same 817 int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1; 818 819 // MOUSE_ENTERED/EXITED are generated for the components strictly under 820 // mouse even when dragging. That's why we first update lastMouseEventPeer 821 // based on initial targetPeer value and only then recalculate targetPeer 822 // for MOUSE_DRAGGED/RELEASED events 823 if (id == MouseEvent.MOUSE_PRESSED) { 824 825 // Ungrab only if this window is not an owned window of the grabbing one. 826 if (!isGrabbing() && grabbingWindow != null && 857 // hidden/removed in between of mouse pressed/released events. 858 targetPeer = mouseDownTarget[targetIdx]; 859 860 if ((modifiers & eventButtonMask) == 0) { 861 mouseDownTarget[targetIdx] = null; 862 } 863 864 // mouseClickButtons is updated below, after MOUSE_CLICK is sent 865 } 866 867 if (targetPeer == null) { 868 //TODO This can happen if this window is invisible. this is correct behavior in this case? 869 targetPeer = this; 870 } 871 872 873 Point lp = targetPeer.windowToLocal(x, y, this); 874 if (targetPeer.isEnabled()) { 875 MouseEvent event = new MouseEvent(targetPeer.getTarget(), id, 876 when, modifiers, lp.x, lp.y, 877 screenX, screenY, clickCount, 878 popupTrigger, button); 879 postEvent(event); 880 } 881 882 if (id == MouseEvent.MOUSE_RELEASED) { 883 if ((mouseClickButtons & eventButtonMask) != 0 884 && targetPeer.isEnabled()) { 885 postEvent(new MouseEvent(targetPeer.getTarget(), 886 MouseEvent.MOUSE_CLICKED, 887 when, modifiers, 888 lp.x, lp.y, screenX, screenY, 889 clickCount, popupTrigger, button)); 890 } 891 mouseClickButtons &= ~eventButtonMask; 892 } 893 } 894 notifyUpdateCursor(); 895 } 896 897 private void generateMouseEnterExitEventsForComponents(long when, 898 int button, int x, int y, int screenX, int screenY, 899 int modifiers, int clickCount, boolean popupTrigger, 900 final LWComponentPeer<?, ?> targetPeer) { 901 902 if (!isMouseOver || targetPeer == lastMouseEventPeer) { 903 return; 904 } 905 906 // Generate Mouse Exit for components 907 if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { 908 Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); 931 MouseEvent.MOUSE_ENTERED, 932 when, modifiers, 933 loc.x, loc.y, xAbs, yAbs, 934 clickCount, popupTrigger, button)); 935 } 936 937 private void postMouseExitedEvent(Component target, long when, int modifiers, 938 Point loc, int xAbs, int yAbs, 939 int clickCount, boolean popupTrigger, int button) { 940 941 updateSecurityWarningVisibility(); 942 943 postEvent(new MouseEvent(target, 944 MouseEvent.MOUSE_EXITED, 945 when, modifiers, 946 loc.x, loc.y, xAbs, yAbs, 947 clickCount, popupTrigger, button)); 948 } 949 950 @Override 951 public void notifyMouseWheelEvent(long when, int x, int y, int modifiers, 952 int scrollType, int scrollAmount, 953 int wheelRotation, double preciseWheelRotation, 954 byte[] bdata) 955 { 956 // TODO: could we just use the last mouse event target here? 957 Rectangle r = getBounds(); 958 // findPeerAt() expects parent coordinates 959 final LWComponentPeer<?, ?> targetPeer = findPeerAt(r.x + x, r.y + y); 960 if (targetPeer == null || !targetPeer.isEnabled()) { 961 return; 962 } 963 964 Point lp = targetPeer.windowToLocal(x, y, this); 965 // TODO: fill "bdata" member of AWTEvent 966 // TODO: screenX/screenY 967 postEvent(new MouseWheelEvent(targetPeer.getTarget(), 968 MouseEvent.MOUSE_WHEEL, 969 when, modifiers, 970 lp.x, lp.y, 971 0, 0, /* screenX, Y */ 972 0 /* clickCount */, false /* popupTrigger */, 973 scrollType, scrollAmount, 974 wheelRotation, preciseWheelRotation)); 975 } 976 977 /* 978 * Called by the delegate when a key is pressed. 979 */ 980 @Override 981 public void notifyKeyEvent(int id, long when, int modifiers, 982 int keyCode, char keyChar, int keyLocation) 983 { 984 LWKeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance(); 985 Component focusOwner = kfmPeer.getCurrentFocusOwner(); 986 987 if (focusOwner == null) { 988 focusOwner = kfmPeer.getCurrentFocusedWindow(); 989 if (focusOwner == null) { 990 focusOwner = this.getTarget(); 991 } | 729 // MouseDown in non-client area 730 @Override 731 public void notifyNCMouseDown() { 732 // Ungrab except for a click on a Dialog with the grabbing owner 733 if (grabbingWindow != null && 734 !grabbingWindow.isOneOfOwnersOf(this)) 735 { 736 grabbingWindow.ungrab(); 737 } 738 } 739 740 // ---- EVENTS ---- // 741 742 /* 743 * Called by the delegate to dispatch the event to Java. Event 744 * coordinates are relative to non-client window are, i.e. the top-left 745 * point of the client area is (insets.top, insets.left). 746 */ 747 @Override 748 public void notifyMouseEvent(int id, long when, int button, 749 int x, int y, int absX, int absY, 750 int modifiers, int clickCount, boolean popupTrigger, 751 byte[] bdata) 752 { 753 // TODO: fill "bdata" member of AWTEvent 754 Rectangle r = getBounds(); 755 // findPeerAt() expects parent coordinates 756 LWComponentPeer<?, ?> targetPeer = findPeerAt(r.x + x, r.y + y); 757 758 if (id == MouseEvent.MOUSE_EXITED) { 759 isMouseOver = false; 760 if (lastMouseEventPeer != null) { 761 if (lastMouseEventPeer.isEnabled()) { 762 Point lp = lastMouseEventPeer.windowToLocal(x, y, 763 this); 764 Component target = lastMouseEventPeer.getTarget(); 765 postMouseExitedEvent(target, when, modifiers, lp, 766 absX, absY, clickCount, popupTrigger, button); 767 } 768 769 // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched 770 // to a peer from another window. So we must first check if this peer is 771 // the same as lastWindowPeer 772 if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) { 773 lastCommonMouseEventPeer = null; 774 } 775 lastMouseEventPeer = null; 776 } 777 } else if(id == MouseEvent.MOUSE_ENTERED) { 778 isMouseOver = true; 779 if (targetPeer != null) { 780 if (targetPeer.isEnabled()) { 781 Point lp = targetPeer.windowToLocal(x, y, this); 782 Component target = targetPeer.getTarget(); 783 postMouseEnteredEvent(target, when, modifiers, lp, 784 absX, absY, clickCount, popupTrigger, button); 785 } 786 lastCommonMouseEventPeer = targetPeer; 787 lastMouseEventPeer = targetPeer; 788 } 789 } else { 790 PlatformWindow topmostPlatformWindow = LWToolkit.getLWToolkit().getPlatformWindowUnderMouse(); 791 792 LWWindowPeer topmostWindowPeer = 793 topmostPlatformWindow != null ? topmostPlatformWindow.getPeer() : null; 794 795 // topmostWindowPeer == null condition is added for the backward 796 // compatibility with applets. It can be removed when the 797 // getTopmostPlatformWindowUnderMouse() method will be properly 798 // implemented in CPlatformEmbeddedFrame class 799 if (topmostWindowPeer == this || topmostWindowPeer == null) { 800 generateMouseEnterExitEventsForComponents(when, button, x, y, 801 absX, absY, modifiers, clickCount, popupTrigger, 802 targetPeer); 803 } else { 804 LWComponentPeer<?, ?> topmostTargetPeer = topmostWindowPeer.findPeerAt(r.x + x, r.y + y); 805 topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y, 806 absX, absY, modifiers, clickCount, popupTrigger, 807 topmostTargetPeer); 808 } 809 810 // TODO: fill "bdata" member of AWTEvent 811 812 int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0; 813 int otherButtonsPressed = modifiers & ~eventButtonMask; 814 815 // For pressed/dragged/released events OS X treats other 816 // mouse buttons as if they were BUTTON2, so we do the same 817 int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1; 818 819 // MOUSE_ENTERED/EXITED are generated for the components strictly under 820 // mouse even when dragging. That's why we first update lastMouseEventPeer 821 // based on initial targetPeer value and only then recalculate targetPeer 822 // for MOUSE_DRAGGED/RELEASED events 823 if (id == MouseEvent.MOUSE_PRESSED) { 824 825 // Ungrab only if this window is not an owned window of the grabbing one. 826 if (!isGrabbing() && grabbingWindow != null && 857 // hidden/removed in between of mouse pressed/released events. 858 targetPeer = mouseDownTarget[targetIdx]; 859 860 if ((modifiers & eventButtonMask) == 0) { 861 mouseDownTarget[targetIdx] = null; 862 } 863 864 // mouseClickButtons is updated below, after MOUSE_CLICK is sent 865 } 866 867 if (targetPeer == null) { 868 //TODO This can happen if this window is invisible. this is correct behavior in this case? 869 targetPeer = this; 870 } 871 872 873 Point lp = targetPeer.windowToLocal(x, y, this); 874 if (targetPeer.isEnabled()) { 875 MouseEvent event = new MouseEvent(targetPeer.getTarget(), id, 876 when, modifiers, lp.x, lp.y, 877 absX, absY, clickCount, 878 popupTrigger, button); 879 postEvent(event); 880 } 881 882 if (id == MouseEvent.MOUSE_RELEASED) { 883 if ((mouseClickButtons & eventButtonMask) != 0 884 && targetPeer.isEnabled()) { 885 postEvent(new MouseEvent(targetPeer.getTarget(), 886 MouseEvent.MOUSE_CLICKED, 887 when, modifiers, 888 lp.x, lp.y, absX, absY, 889 clickCount, popupTrigger, button)); 890 } 891 mouseClickButtons &= ~eventButtonMask; 892 } 893 } 894 notifyUpdateCursor(); 895 } 896 897 private void generateMouseEnterExitEventsForComponents(long when, 898 int button, int x, int y, int screenX, int screenY, 899 int modifiers, int clickCount, boolean popupTrigger, 900 final LWComponentPeer<?, ?> targetPeer) { 901 902 if (!isMouseOver || targetPeer == lastMouseEventPeer) { 903 return; 904 } 905 906 // Generate Mouse Exit for components 907 if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { 908 Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); 931 MouseEvent.MOUSE_ENTERED, 932 when, modifiers, 933 loc.x, loc.y, xAbs, yAbs, 934 clickCount, popupTrigger, button)); 935 } 936 937 private void postMouseExitedEvent(Component target, long when, int modifiers, 938 Point loc, int xAbs, int yAbs, 939 int clickCount, boolean popupTrigger, int button) { 940 941 updateSecurityWarningVisibility(); 942 943 postEvent(new MouseEvent(target, 944 MouseEvent.MOUSE_EXITED, 945 when, modifiers, 946 loc.x, loc.y, xAbs, yAbs, 947 clickCount, popupTrigger, button)); 948 } 949 950 @Override 951 public void notifyMouseWheelEvent(long when, int x, int y, int absX, 952 int absY, int modifiers, int scrollType, 953 int scrollAmount, int wheelRotation, 954 double preciseWheelRotation, byte[] bdata) 955 { 956 // TODO: could we just use the last mouse event target here? 957 Rectangle r = getBounds(); 958 // findPeerAt() expects parent coordinates 959 final LWComponentPeer<?, ?> targetPeer = findPeerAt(r.x + x, r.y + y); 960 if (targetPeer == null || !targetPeer.isEnabled()) { 961 return; 962 } 963 964 Point lp = targetPeer.windowToLocal(x, y, this); 965 // TODO: fill "bdata" member of AWTEvent 966 postEvent(new MouseWheelEvent(targetPeer.getTarget(), 967 MouseEvent.MOUSE_WHEEL, 968 when, modifiers, 969 lp.x, lp.y, 970 absX, absY, /* absX, absY */ 971 0 /* clickCount */, false /* popupTrigger */, 972 scrollType, scrollAmount, 973 wheelRotation, preciseWheelRotation)); 974 } 975 976 /* 977 * Called by the delegate when a key is pressed. 978 */ 979 @Override 980 public void notifyKeyEvent(int id, long when, int modifiers, 981 int keyCode, char keyChar, int keyLocation) 982 { 983 LWKeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance(); 984 Component focusOwner = kfmPeer.getCurrentFocusOwner(); 985 986 if (focusOwner == null) { 987 focusOwner = kfmPeer.getCurrentFocusedWindow(); 988 if (focusOwner == null) { 989 focusOwner = this.getTarget(); 990 } |