--- old/src/java.desktop/share/classes/sun/awt/im/ExecutableInputMethodManager.java 2018-06-15 02:43:18.985822204 +0900 +++ new/src/java.desktop/share/classes/sun/awt/im/ExecutableInputMethodManager.java 2018-06-15 02:43:18.365835255 +0900 @@ -55,6 +55,10 @@ import java.util.prefs.Preferences; import sun.awt.InputMethodSupport; import sun.awt.SunToolkit; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JRootPane; +import java.awt.KeyboardFocusManager; /** * {@code ExecutableInputMethodManager} is the implementation of the @@ -89,6 +93,7 @@ // component that is requesting input method switch // must be Frame or Dialog private Component requestComponent; + private Component invokerComponent; // input context that is requesting input method switch private InputContext requestInputContext; @@ -212,10 +217,23 @@ return; requestComponent = comp; + if (comp instanceof JDialog) { + if (!(comp.getParent() instanceof JFrame)) + invokerComponent = comp; + } + if (invokerComponent==null) { + invokerComponent = KeyboardFocusManager.getCurrentKeyboardFocusManager() + .getFocusOwner(); + if (invokerComponent !=null && !invokerComponent.isShowing()) + invokerComponent = comp; + } + if (invokerComponent==null) + invokerComponent = comp; notify(); } public synchronized void notifyChangeRequestByHotKey(Component comp) { + invokerComponent = comp; while (!(comp instanceof Frame || comp instanceof Dialog)) { if (comp == null) { // no Frame or Dialog found in containment hierarchy. @@ -288,11 +306,27 @@ if (!hasMultipleInputMethods()) { requestComponent = null; + invokerComponent = null; return; } // initialize pop-up menu - selectionMenu = InputMethodPopupMenu.getInstance(requestComponent, selectInputMethodMenuTitle); + if (requestComponent != null && requestComponent.equals(invokerComponent)) { + selectionMenu = InputMethodPopupMenu.getAWTInstance(requestComponent, + selectInputMethodMenuTitle); + } else { + selectionMenu = InputMethodPopupMenu.getInstance(requestComponent, + selectInputMethodMenuTitle); + } + if (invokerComponent instanceof JRootPane) { + if (selectionMenu.isVisible()) { + synchronized (this) { + requestComponent = null; + invokerComponent = null; + } + return; + } + } // we have to rebuild the menu each time because // some input methods (such as IIIMP) may change @@ -317,10 +351,23 @@ } synchronized (this) { - selectionMenu.addToComponent(requestComponent); - requestInputContext = currentInputContext; - selectionMenu.show(requestComponent, 60, 80); // TODO: get proper x, y... + if (requestComponent == null){ + requestInputContext = currentInputContext; + selectionMenu.show(requestComponent, 0, 0); + } else { + int offsetX = 60; + int offsetY = 80; + selectionMenu.addToComponent(requestComponent); + requestInputContext = currentInputContext; + if (requestComponent.getSize().width < offsetX * 2) + offsetX = requestComponent.getSize().width / 2; + if (requestComponent.getSize().height < offsetY * 2) + offsetY = requestComponent.getSize().height / 2; + selectionMenu.show(requestComponent, offsetX, offsetY); + } requestComponent = null; + invokerComponent = null; + } } --- old/src/java.desktop/share/classes/sun/awt/im/InputMethodPopupMenu.java 2018-06-15 02:43:19.835804311 +0900 +++ new/src/java.desktop/share/classes/sun/awt/im/InputMethodPopupMenu.java 2018-06-15 02:43:19.216817341 +0900 @@ -44,6 +44,8 @@ import javax.swing.JPopupMenu; import javax.swing.JMenu; import javax.swing.JMenuItem; +import javax.swing.JWindow; +import javax.swing.SwingUtilities; /** * {@code InputMethodPopupMenu} provides the popup selection menu @@ -56,13 +58,20 @@ // is created. static InputMethodPopupMenu getInstance(Component client, String title) { if ((client instanceof JFrame) || - (client instanceof JDialog)) { + (client instanceof JDialog) || + (client instanceof JWindow)) { return new JInputMethodPopupMenu(title); } else { return new AWTInputMethodPopupMenu(title); } } + static InputMethodPopupMenu getAWTInstance(Component client, String title) { + return new AWTInputMethodPopupMenu(title); + } + + abstract boolean isVisible(); + abstract void show(Component c, int x, int y); abstract void removeAll(); @@ -175,7 +184,12 @@ } } + boolean isVisible() { + return delegate.isVisible(); + } + void show(Component c, int x, int y) { + SwingUtilities.updateComponentTreeUI(delegate); delegate.show(c, x, y); } @@ -232,6 +246,10 @@ } } + boolean isVisible() { + return false; + } + void show(Component c, int x, int y) { delegate.show(c, x, y); }