OpenJDK / jdk / jdk10
changeset 26005:25124e230434
8046495: KeyEvent can not be accepted in quick mouse clicking
Reviewed-by: art, pchelko
author | anashaty |
---|---|
date | Thu, 24 Jul 2014 16:06:49 +0100 |
parents | 7507a1b93f67 |
children | da0572ecab20 |
files | jdk/src/windows/native/sun/windows/awt_Button.cpp jdk/src/windows/native/sun/windows/awt_Component.cpp jdk/src/windows/native/sun/windows/awt_Component.h jdk/src/windows/native/sun/windows/awt_List.cpp jdk/src/windows/native/sun/windows/awt_MenuItem.cpp jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp jdk/src/windows/native/sun/windows/awt_Window.cpp jdk/test/java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java |
diffstat | 8 files changed, 159 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/windows/native/sun/windows/awt_Button.cpp Thu Jul 24 17:36:56 2014 +0400 +++ b/jdk/src/windows/native/sun/windows/awt_Button.cpp Thu Jul 24 16:06:49 2014 +0100 @@ -186,7 +186,7 @@ void AwtButton::NotifyListeners() { - DoCallback("handleAction", "(JI)V", TimeHelper::getMessageTimeUTC(), + DoCallback("handleAction", "(JI)V", ::JVM_CurrentTimeMillis(NULL, 0), (jint)AwtComponent::GetJavaModifiers()); }
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Thu Jul 24 17:36:56 2014 +0400 +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Thu Jul 24 16:06:49 2014 +0100 @@ -2125,37 +2125,6 @@ return mrDoDefault; } -namespace TimeHelper { - // Sometimes the message belongs to another event queue and - // GetMessageTime() may return wrong non-zero value (the case is - // the TrayIcon peer). Using TimeHelper::windowsToUTC(::GetTickCount()) - // could help there. - static DWORD getMessageTimeWindows(){ - DWORD time = ::GetMessageTime(); - // The following 'if' seems to be a unneeded hack. - // Consider removing it. - if (time == 0) { - time = ::GetTickCount(); - } - return time; - } - - jlong getMessageTimeUTC() { - return windowsToUTC(getMessageTimeWindows()); - } - - // If calling order of GetTickCount and JVM_CurrentTimeMillis - // is swapped, it would sometimes give different result. - // Anyway, we would not always have determinism - // and sortedness of time conversion here (due to Windows's - // timers peculiarities). Having some euristic algorithm might - // help here. - jlong windowsToUTC(DWORD windowsTime) { - jlong offset = ::GetTickCount() - windowsTime; - jlong jvm_time = ::JVM_CurrentTimeMillis(NULL, 0); - return jvm_time - offset; - } -} //TimeHelper MsgRouting AwtComponent::WmPaint(HDC) { @@ -2253,7 +2222,7 @@ MsgRouting AwtComponent::WmMouseEnter(UINT flags, int x, int y) { SendMouseEvent(java_awt_event_MouseEvent_MOUSE_ENTERED, - TimeHelper::getMessageTimeUTC(), x, y, GetJavaModifiers(), 0, JNI_FALSE); + ::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(), 0, JNI_FALSE); if ((flags & ALL_MK_BUTTONS) == 0) { AwtCursor::UpdateCursor(this); } @@ -2288,7 +2257,7 @@ msg->message = message; msg->wParam = wParam; msg->lParam = lParam; - msg->time = TimeHelper::getMessageTimeWindows(); + msg->time = ::GetMessageTime(); msg->pt.x = x; msg->pt.y = y; } @@ -2327,7 +2296,7 @@ MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button) { - jlong now = TimeHelper::getMessageTimeUTC(); + jlong now = ::JVM_CurrentTimeMillis(NULL, 0); if (lastClickWnd == this && lastButton == button && @@ -2392,7 +2361,7 @@ MSG msg; InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); - SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, TimeHelper::getMessageTimeUTC(), + SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, ::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(), clickCount, (GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ? TRUE : FALSE), GetButton(button), &msg); @@ -2403,7 +2372,7 @@ */ if ((m_mouseButtonClickAllowed & GetButtonMK(button)) != 0) { //CLICK allowed SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED, - TimeHelper::getMessageTimeUTC(), x, y, GetJavaModifiers(), + ::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(), clickCount, JNI_FALSE, GetButton(button)); } // Exclude button from allowed to generate CLICK messages @@ -2452,7 +2421,7 @@ // This is a partial backout of 5039416 fix. MSG msg; InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); - SendMouseEvent(java_awt_event_MouseEvent_MOUSE_DRAGGED, TimeHelper::getMessageTimeUTC(), x, y, + SendMouseEvent(java_awt_event_MouseEvent_MOUSE_DRAGGED, ::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(), 0, JNI_FALSE, java_awt_event_MouseEvent_NOBUTTON, &msg); //dragging means no more CLICKs until next WM_MOUSE_DOWN/WM_MOUSE_UP message sequence @@ -2460,7 +2429,7 @@ } else { MSG msg; InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); - SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::getMessageTimeUTC(), x, y, + SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, ::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(), 0, JNI_FALSE, java_awt_event_MouseEvent_NOBUTTON, &msg); } @@ -2471,7 +2440,7 @@ MsgRouting AwtComponent::WmMouseExit(UINT flags, int x, int y) { - SendMouseEvent(java_awt_event_MouseEvent_MOUSE_EXITED, TimeHelper::getMessageTimeUTC(), x, + SendMouseEvent(java_awt_event_MouseEvent_MOUSE_EXITED, ::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(), 0, JNI_FALSE); sm_cursorOn = NULL; return mrConsume; /* Don't pass our synthetic event on! */ @@ -2523,7 +2492,7 @@ DTRACE_PRINTLN("calling SendMouseWheelEvent"); - SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(), + SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, ::JVM_CurrentTimeMillis(NULL, 0), eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType, scrollLines, roundedWheelRotation, preciseWheelRotation, &msg); @@ -3578,7 +3547,7 @@ SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED, - TimeHelper::windowsToUTC(msg.time), jkey, character, + ::JVM_CurrentTimeMillis(NULL, 0), jkey, character, modifiers, keyLocation, (jlong)wkey, &msg); // bugid 4724007: Windows does not create a WM_CHAR for the Del key @@ -3588,7 +3557,7 @@ // for Java - we don't want Windows trying to process it). if (jkey == java_awt_event_KeyEvent_VK_DELETE) { SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, - TimeHelper::windowsToUTC(msg.time), + ::JVM_CurrentTimeMillis(NULL, 0), java_awt_event_KeyEvent_VK_UNDEFINED, character, modifiers, java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0); @@ -3620,7 +3589,7 @@ UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED, - TimeHelper::windowsToUTC(msg.time), jkey, character, + ::JVM_CurrentTimeMillis(NULL, 0), jkey, character, modifiers, keyLocation, (jlong)wkey, &msg); return mrConsume; } @@ -3665,7 +3634,7 @@ jint modifiers = GetJavaModifiers(); SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, - TimeHelper::windowsToUTC(msg.time), + ::JVM_CurrentTimeMillis(NULL, 0), java_awt_event_KeyEvent_VK_UNDEFINED, unicodeChar, modifiers, java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, @@ -3734,7 +3703,7 @@ InitMessage(&msg, message, character, MAKELPARAM(repCnt, flags)); SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, - TimeHelper::windowsToUTC(msg.time), + ::JVM_CurrentTimeMillis(NULL, 0), java_awt_event_KeyEvent_VK_UNDEFINED, unicodeChar, modifiers, java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, @@ -4020,7 +3989,7 @@ } // call m_InputMethod.sendInputMethod() - env->CallVoidMethod(m_InputMethod, sendIMEventMid, id, TimeHelper::getMessageTimeUTC(), + env->CallVoidMethod(m_InputMethod, sendIMEventMid, id, ::JVM_CurrentTimeMillis(NULL, 0), text, clauseBoundary, clauseReading, attrBoundary, attrValue, commitedTextLength, caretPos, visiblePos); if (safe_ExceptionOccurred(env)) env->ExceptionDescribe();
--- a/jdk/src/windows/native/sun/windows/awt_Component.h Thu Jul 24 17:36:56 2014 +0400 +++ b/jdk/src/windows/native/sun/windows/awt_Component.h Thu Jul 24 16:06:49 2014 +0100 @@ -908,11 +908,6 @@ void ReleaseDCList(HWND hwnd, DCList &list); void MoveDCToPassiveList(HDC hDC); -namespace TimeHelper{ - jlong getMessageTimeUTC(); - jlong windowsToUTC(DWORD event_offset); -} - #include "ObjectList.h" #endif /* AWT_COMPONENT_H */
--- a/jdk/src/windows/native/sun/windows/awt_List.cpp Thu Jul 24 17:36:56 2014 +0400 +++ b/jdk/src/windows/native/sun/windows/awt_List.cpp Thu Jul 24 16:06:49 2014 +0100 @@ -535,7 +535,7 @@ } else if (notifyCode == LBN_DBLCLK) { DoCallback("handleAction", "(IJI)V", nCurrentSelection, - TimeHelper::getMessageTimeUTC(), + ::JVM_CurrentTimeMillis(NULL, 0), (jint)AwtComponent::GetJavaModifiers()); } }
--- a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp Thu Jul 24 17:36:56 2014 +0400 +++ b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp Thu Jul 24 16:06:49 2014 +0100 @@ -665,7 +665,7 @@ DASSERT(nState != 0xFFFFFFFF); DoCallback("handleAction", "(Z)V", ((nState & MF_CHECKED) == 0)); } else { - DoCallback("handleAction", "(JI)V", TimeHelper::getMessageTimeUTC(), + DoCallback("handleAction", "(JI)V", ::JVM_CurrentTimeMillis(NULL, 0), (jint)AwtComponent::GetJavaModifiers()); } }
--- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Thu Jul 24 17:36:56 2014 +0400 +++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Thu Jul 24 16:06:49 2014 +0100 @@ -325,7 +325,7 @@ MsgRouting AwtTrayIcon::WmMouseDown(UINT flags, int x, int y, int button) { - jlong now = TimeHelper::windowsToUTC(::GetTickCount()); + jlong now = ::JVM_CurrentTimeMillis(NULL, 0); jint javaModif = AwtComponent::GetJavaModifiers(); if (lastClickTrIc == this && @@ -361,14 +361,14 @@ MSG msg; AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); - SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, TimeHelper::windowsToUTC(::GetTickCount()), + SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, ::JVM_CurrentTimeMillis(NULL, 0), x, y, AwtComponent::GetJavaModifiers(), clickCount, (AwtComponent::GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ? TRUE : FALSE), AwtComponent::GetButton(button), &msg); if ((m_mouseButtonClickAllowed & AwtComponent::GetButtonMK(button)) != 0) { // No up-button in the drag-state SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED, - TimeHelper::windowsToUTC(::GetTickCount()), x, y, AwtComponent::GetJavaModifiers(), + ::JVM_CurrentTimeMillis(NULL, 0), x, y, AwtComponent::GetJavaModifiers(), clickCount, JNI_FALSE, AwtComponent::GetButton(button)); } m_mouseButtonClickAllowed &= ~AwtComponent::GetButtonMK(button); // Exclude the up-button from the drag-state @@ -395,7 +395,7 @@ if ((flags & ALL_MK_BUTTONS) != 0) { m_mouseButtonClickAllowed = 0; } else { - SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::windowsToUTC(::GetTickCount()), x, y, + SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, ::JVM_CurrentTimeMillis(NULL, 0), x, y, AwtComponent::GetJavaModifiers(), 0, JNI_FALSE, java_awt_event_MouseEvent_NOBUTTON, &msg); } @@ -408,7 +408,7 @@ if (AwtComponent::GetJavaModifiers() & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) { MSG msg; AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); - SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::windowsToUTC(::GetTickCount()), + SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, ::JVM_CurrentTimeMillis(NULL, 0), AwtComponent::GetJavaModifiers(), &msg); } return mrConsume; @@ -417,14 +417,14 @@ MsgRouting AwtTrayIcon::WmKeySelect(UINT flags, int x, int y) { static jlong lastKeySelectTime = 0; - jlong now = TimeHelper::windowsToUTC(::GetTickCount()); + jlong now = ::JVM_CurrentTimeMillis(NULL, 0); // If a user selects a notify icon with the ENTER key, // Shell 5.0 sends double NIN_KEYSELECT notification. if (lastKeySelectTime != now) { MSG msg; AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); - SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::windowsToUTC(::GetTickCount()), + SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, ::JVM_CurrentTimeMillis(NULL, 0), AwtComponent::GetJavaModifiers(), &msg); } lastKeySelectTime = now; @@ -441,7 +441,7 @@ if (clickCount == 2) { MSG msg; AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); - SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::windowsToUTC(::GetTickCount()), + SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, ::JVM_CurrentTimeMillis(NULL, 0), AwtComponent::GetJavaModifiers(), &msg); } return mrConsume;
--- a/jdk/src/windows/native/sun/windows/awt_Window.cpp Thu Jul 24 17:36:56 2014 +0400 +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Thu Jul 24 16:06:49 2014 +0100 @@ -1552,7 +1552,7 @@ } } jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id, - jOpposite, oldState, newState, TimeHelper::getMessageTimeUTC()); + jOpposite, oldState, newState, ::JVM_CurrentTimeMillis(NULL, 0)); DASSERT(!safe_ExceptionOccurred(env)); DASSERT(event != NULL); if (jOpposite != NULL) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java Thu Jul 24 16:06:49 2014 +0100 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import sun.awt.SunToolkit; + +import java.awt.*; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 8046495 + * @summary Verifies that mouse/key events has always increasing 'when' timestamps + * @author Anton Nashatyrev + * @run main EventWhenTest + */ +public class EventWhenTest { + + private static volatile int eventsCount = 0; + private static volatile boolean failed = false; + + static { + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + long lastWhen = 0; + + @Override + public void eventDispatched(AWTEvent event) { + long curWhen; + if (event instanceof KeyEvent) { + curWhen = ((KeyEvent) event).getWhen(); + } else if (event instanceof MouseEvent) { + curWhen = ((MouseEvent) event).getWhen(); + } else { + return; + } + + eventsCount++; + + if (curWhen < lastWhen) { + System.err.println("FAILED: " + curWhen + " < " + lastWhen + + " for " + event); + failed = true; + } else { + lastWhen = curWhen; + } + } + }, AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK); + } + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Frame frame = new Frame(); + + try { + Button b = new Button("Button"); + frame.setBounds(300, 300, 300, 300); + frame.add(b); + frame.setVisible(true); + toolkit.realSync(); + + Robot robot = new Robot(); + robot.mouseMove((int)frame.getLocationOnScreen().getX() + 150, + (int)frame.getLocationOnScreen().getY() + 150); + + eventsCount = 0; + System.out.println("Clicking mouse..."); + for (int i = 0; i < 300 && !failed; i++) { + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Thread.sleep(10); + b.setLabel("Click: " + i); + } + + if (eventsCount == 0) { + throw new RuntimeException("No events were received"); + } + + if (failed) { + throw new RuntimeException("Test failed."); + } + System.out.println("Clicking mouse done: " + eventsCount + " events."); + + b.requestFocusInWindow(); + toolkit.realSync(); + + eventsCount = 0; + System.out.println("Typing a key..."); + for (int i = 0; i < 300 && !failed; i++) { + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + Thread.sleep(10); + b.setLabel("Type: " + i); + } + System.out.println("Key typing done: " + eventsCount + " events."); + + if (eventsCount == 0) { + throw new RuntimeException("No events were received"); + } + + if (failed) { + throw new RuntimeException("Test failed."); + } + + System.out.println("Success!"); + } finally { + frame.dispose(); + } + } +}