diff options
author | anashaty <none@none> | 2014-07-30 12:01:47 +0100 |
---|---|---|
committer | anashaty <none@none> | 2014-07-30 12:01:47 +0100 |
commit | a8e488e8a32ac235079e117e9374221deda7ac87 (patch) | |
tree | 853e59ba45f8d06e82fbe7a10c332ab9e247e08e | |
parent | 625175acd01ada6be84bff0d1d927fac679027aa (diff) |
8046495: KeyEvent can not be accepted in quick mouse clicking
Reviewed-by: art, pchelko
-rw-r--r-- | src/windows/native/sun/windows/awt_Component.cpp | 24 | ||||
-rw-r--r-- | src/windows/native/sun/windows/awt_TrayIcon.cpp | 16 | ||||
-rw-r--r-- | test/java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java | 132 |
3 files changed, 146 insertions, 26 deletions
diff --git a/src/windows/native/sun/windows/awt_Component.cpp b/src/windows/native/sun/windows/awt_Component.cpp index 5ab74c7e8..d8148f9d0 100644 --- a/src/windows/native/sun/windows/awt_Component.cpp +++ b/src/windows/native/sun/windows/awt_Component.cpp @@ -2141,19 +2141,7 @@ namespace TimeHelper { } 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; + return ::JVM_CurrentTimeMillis(NULL, 0); } } //TimeHelper @@ -3578,7 +3566,7 @@ MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt, SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED, - TimeHelper::windowsToUTC(msg.time), jkey, character, + TimeHelper::getMessageTimeUTC(), jkey, character, modifiers, keyLocation, (jlong)wkey, &msg); // bugid 4724007: Windows does not create a WM_CHAR for the Del key @@ -3588,7 +3576,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), + TimeHelper::getMessageTimeUTC(), java_awt_event_KeyEvent_VK_UNDEFINED, character, modifiers, java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0); @@ -3620,7 +3608,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, + TimeHelper::getMessageTimeUTC(), jkey, character, modifiers, keyLocation, (jlong)wkey, &msg); return mrConsume; } @@ -3665,7 +3653,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), + TimeHelper::getMessageTimeUTC(), java_awt_event_KeyEvent_VK_UNDEFINED, unicodeChar, modifiers, java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, @@ -3734,7 +3722,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), + TimeHelper::getMessageTimeUTC(), java_awt_event_KeyEvent_VK_UNDEFINED, unicodeChar, modifiers, java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, diff --git a/src/windows/native/sun/windows/awt_TrayIcon.cpp b/src/windows/native/sun/windows/awt_TrayIcon.cpp index d453101ef..a7e707842 100644 --- a/src/windows/native/sun/windows/awt_TrayIcon.cpp +++ b/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 = TimeHelper::getMessageTimeUTC(); 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, TimeHelper::getMessageTimeUTC(), 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(), + TimeHelper::getMessageTimeUTC(), 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, TimeHelper::getMessageTimeUTC(), 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, TimeHelper::getMessageTimeUTC(), 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 = TimeHelper::getMessageTimeUTC(); // 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, TimeHelper::getMessageTimeUTC(), 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, TimeHelper::getMessageTimeUTC(), AwtComponent::GetJavaModifiers(), &msg); } return mrConsume; diff --git a/test/java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java b/test/java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java new file mode 100644 index 000000000..2c07f313c --- /dev/null +++ b/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(); + } + } +} |