From da90b6a6682b5fb7632bfde407927eaf7f36ee9c Mon Sep 17 00:00:00 2001 From: dmarkov Date: Tue, 5 Aug 2014 08:30:05 +0400 Subject: [PATCH] 8041990: [macosx] Language specific keys does not work in applets when opened outside the browser Reviewed-by: alexsch, serb --- src/share/classes/java/awt/EventQueue.java | 5 + .../java/awt/event/InputMethodEvent.java | 35 +++++- src/share/classes/sun/awt/AWTAccessor.java | 7 +- test/java/awt/im/8041990/bug8041990.java | 104 ++++++++++++++++++ 4 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 test/java/awt/im/8041990/bug8041990.java diff --git a/src/share/classes/java/awt/EventQueue.java b/src/share/classes/java/awt/EventQueue.java index ef467b207..f19cfdab6 100644 --- a/src/share/classes/java/awt/EventQueue.java +++ b/src/share/classes/java/awt/EventQueue.java @@ -214,6 +214,11 @@ public class EventQueue { FwDispatcher dispatcher) { eventQueue.setFwDispatcher(dispatcher); } + + @Override + public long getMostRecentEventTime(EventQueue eventQueue) { + return eventQueue.getMostRecentEventTimeImpl(); + } }); } diff --git a/src/share/classes/java/awt/event/InputMethodEvent.java b/src/share/classes/java/awt/event/InputMethodEvent.java index ec5548a8b..cd7122d52 100644 --- a/src/share/classes/java/awt/event/InputMethodEvent.java +++ b/src/share/classes/java/awt/event/InputMethodEvent.java @@ -25,6 +25,10 @@ package java.awt.event; +import sun.awt.AWTAccessor; +import sun.awt.AppContext; +import sun.awt.SunToolkit; + import java.awt.AWTEvent; import java.awt.Component; import java.awt.EventQueue; @@ -217,8 +221,10 @@ public class InputMethodEvent extends AWTEvent { public InputMethodEvent(Component source, int id, AttributedCharacterIterator text, int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition) { - this(source, id, EventQueue.getMostRecentEventTime(), text, - committedCharacterCount, caret, visiblePosition); + this(source, id, + getMostRecentEventTimeForSource(source), + text, committedCharacterCount, + caret, visiblePosition); } /** @@ -258,8 +264,9 @@ public class InputMethodEvent extends AWTEvent { */ public InputMethodEvent(Component source, int id, TextHitInfo caret, TextHitInfo visiblePosition) { - this(source, id, EventQueue.getMostRecentEventTime(), null, - 0, caret, visiblePosition); + this(source, id, + getMostRecentEventTimeForSource(source), + null, 0, caret, visiblePosition); } /** @@ -410,7 +417,25 @@ public class InputMethodEvent extends AWTEvent { private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { s.defaultReadObject(); if (when == 0) { - when = EventQueue.getMostRecentEventTime(); + when = getMostRecentEventTimeForSource(this.source); + } + } + + /** + * Get the most recent event time in the {@code EventQueue} which the {@code source} + * belongs to. + * + * @param source the source of the event + * @exception IllegalArgumentException if source is null. + * @return most recent event time in the {@code EventQueue} + */ + private static long getMostRecentEventTimeForSource(Object source) { + if (source == null) { + // throw the IllegalArgumentException to conform to EventObject spec + throw new IllegalArgumentException("null source"); } + AppContext appContext = SunToolkit.targetToAppContext(source); + EventQueue eventQueue = SunToolkit.getSystemEventQueueImplPP(appContext); + return AWTAccessor.getEventQueueAccessor().getMostRecentEventTime(eventQueue); } } diff --git a/src/share/classes/sun/awt/AWTAccessor.java b/src/share/classes/sun/awt/AWTAccessor.java index 38b853842..d491ebef2 100644 --- a/src/share/classes/sun/awt/AWTAccessor.java +++ b/src/share/classes/sun/awt/AWTAccessor.java @@ -504,7 +504,12 @@ public final class AWTAccessor { /** * Sets the delegate for the EventQueue used by FX/AWT single threaded mode */ - public void setFwDispatcher(EventQueue eventQueue, FwDispatcher dispatcher); + void setFwDispatcher(EventQueue eventQueue, FwDispatcher dispatcher); + + /** + * Gets most recent event time in the EventQueue + */ + long getMostRecentEventTime(EventQueue eventQueue); } /* diff --git a/test/java/awt/im/8041990/bug8041990.java b/test/java/awt/im/8041990/bug8041990.java new file mode 100644 index 000000000..ee813e671 --- /dev/null +++ b/test/java/awt/im/8041990/bug8041990.java @@ -0,0 +1,104 @@ +/* + * 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. + */ + + +/* + @test + @bug 8041990 + @summary Language specific keys does not work in applets when opened outside the browser + @author Petr Pchelko +*/ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.InputMethodEvent; +import java.awt.font.TextHitInfo; +import java.text.AttributedString; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +public class bug8041990 { + private static JFrame frame; + private static JComponent component; + + public static void main(String[] args) throws Exception { + ThreadGroup stubTG = new ThreadGroup(getRootThreadGroup(), "Stub Thread Group"); + ThreadGroup swingTG = new ThreadGroup(getRootThreadGroup(), "SwingTG"); + try { + Thread stubThread = new Thread(stubTG, SunToolkit::createNewAppContext); + stubThread.start(); + stubThread.join(); + + CountDownLatch startSwingLatch = new CountDownLatch(1); + new Thread(swingTG, () -> { + SunToolkit.createNewAppContext(); + SwingUtilities.invokeLater(() -> { + frame = new JFrame(); + component = new JLabel("Test Text"); + frame.add(component); + frame.setBounds(100, 100, 100, 100); + frame.setVisible(true); + startSwingLatch.countDown(); + }); + }).start(); + startSwingLatch.await(); + + AtomicReference caughtException = new AtomicReference<>(); + Thread checkThread = new Thread(getRootThreadGroup(), () -> { + try { + // If the bug is present this will throw exception + new InputMethodEvent(component, + InputMethodEvent.CARET_POSITION_CHANGED, + TextHitInfo.leading(0), + TextHitInfo.trailing(0)); + } catch (Exception e) { + caughtException.set(e); + } + }); + checkThread.start(); + checkThread.join(); + + if (caughtException.get() != null) { + throw new RuntimeException("Failed. Caught exception!", caughtException.get()); + } + } finally { + new Thread(swingTG, () -> SwingUtilities.invokeLater(() -> { + if (frame != null) { + frame.dispose(); + } + })).start(); + } + } + + private static ThreadGroup getRootThreadGroup() { + ThreadGroup currentTG = Thread.currentThread().getThreadGroup(); + ThreadGroup parentTG = currentTG.getParent(); + while (parentTG != null) { + currentTG = parentTG; + parentTG = currentTG.getParent(); + } + return currentTG; + } +} -- GitLab