diff --git a/jdk/src/windows/native/sun/windows/awt_Button.cpp b/jdk/src/windows/native/sun/windows/awt_Button.cpp index 95f868ec59f..21644a532b5 100644 --- a/jdk/src/windows/native/sun/windows/awt_Button.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Button.cpp @@ -186,7 +186,7 @@ AwtButton::WmMouseUp(UINT flags, int x, int y, int button) void AwtButton::NotifyListeners() { - DoCallback("handleAction", "(JI)V", TimeHelper::getMessageTimeUTC(), + DoCallback("handleAction", "(JI)V", ::JVM_CurrentTimeMillis(NULL, 0), (jint)AwtComponent::GetJavaModifiers()); } diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 5ab74c7e858..135e7c541e3 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -2125,37 +2125,6 @@ MsgRouting AwtComponent::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollbar) 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 @@ void AwtComponent::PaintUpdateRgn(const RECT *insets) 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 @@ AwtComponent::InitMessage(MSG* msg, UINT message, WPARAM wParam, LPARAM lParam, 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 @@ int AwtComponent::GetClickCount() 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 @@ MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button) 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 @@ MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button) */ 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 @@ MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y) // 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 @@ MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y) } 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::WmMouseMove(UINT flags, int x, int y) 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 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y, 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 @@ MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt, 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 @@ MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt, // 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 @@ MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt, 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 @@ MsgRouting AwtComponent::WmIMEChar(UINT character, UINT repCnt, UINT flags, BOOL 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 @@ MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags, 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 @@ void AwtComponent::SendInputMethodEvent(jint id, jstring text, } // 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(); diff --git a/jdk/src/windows/native/sun/windows/awt_Component.h b/jdk/src/windows/native/sun/windows/awt_Component.h index f3f34098b70..9fe2754142b 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.h +++ b/jdk/src/windows/native/sun/windows/awt_Component.h @@ -908,11 +908,6 @@ public: 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 */ diff --git a/jdk/src/windows/native/sun/windows/awt_List.cpp b/jdk/src/windows/native/sun/windows/awt_List.cpp index 5188c85984f..39016b9ab59 100644 --- a/jdk/src/windows/native/sun/windows/awt_List.cpp +++ b/jdk/src/windows/native/sun/windows/awt_List.cpp @@ -535,7 +535,7 @@ AwtList::WmNotify(UINT notifyCode) } else if (notifyCode == LBN_DBLCLK) { DoCallback("handleAction", "(IJI)V", nCurrentSelection, - TimeHelper::getMessageTimeUTC(), + ::JVM_CurrentTimeMillis(NULL, 0), (jint)AwtComponent::GetJavaModifiers()); } } diff --git a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp index cb0f380c715..c0a0120c79e 100644 --- a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp +++ b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp @@ -665,7 +665,7 @@ void AwtMenuItem::DoCommand() 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()); } } diff --git a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp index d453101efe1..7952f1e7382 100644 --- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp +++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp @@ -325,7 +325,7 @@ static int clickCount = 0; 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 @@ MsgRouting AwtTrayIcon::WmMouseUp(UINT flags, int x, int y, int button) 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 @@ MsgRouting AwtTrayIcon::WmMouseMove(UINT flags, int x, int y) 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 @@ MsgRouting AwtTrayIcon::WmBalloonUserClick(UINT flags, int x, int y) 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::WmBalloonUserClick(UINT flags, int x, int y) 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 @@ MsgRouting AwtTrayIcon::WmSelect(UINT flags, int x, int y) 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; diff --git a/jdk/src/windows/native/sun/windows/awt_Window.cpp b/jdk/src/windows/native/sun/windows/awt_Window.cpp index 1242bba63c8..4a3bcfcad7d 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp @@ -1552,7 +1552,7 @@ void AwtWindow::SendWindowEvent(jint id, HWND opposite, } } 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) { diff --git a/jdk/test/java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java b/jdk/test/java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java new file mode 100644 index 00000000000..2c07f313ca5 --- /dev/null +++ b/jdk/test/java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java @@ -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(); + } + } +}