< prev index next >

src/java.desktop/share/classes/sun/awt/im/ExecutableInputMethodManager.java

Print this page

        

@@ -53,10 +53,14 @@
 import java.util.Set;
 import java.util.prefs.BackingStoreException;
 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
  * {@code InputMethodManager} class. It is runnable as a separate
  * thread in the AWT environment.&nbsp;

@@ -87,10 +91,11 @@
     private Vector<InputMethodLocator> javaInputMethodLocatorList;
 
     // 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;
 
     // IM preference stuff

@@ -210,14 +215,27 @@
         // if busy with the current request, ignore this request.
         if (requestComponent != null)
             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.
                 return;
             }

@@ -286,15 +304,31 @@
 
     private void showInputMethodMenu() {
 
         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
         // their list of supported locales dynamically
         selectionMenu.removeAll();

@@ -315,14 +349,27 @@
             InputMethodLocator locator = javaInputMethodLocatorList.get(i);
             selectionMenu.addOneInputMethodToMenu(locator, currentSelection);
         }
 
         synchronized (this) {
+            if (requestComponent == null){
+                requestInputContext = currentInputContext;
+                selectionMenu.show(requestComponent, 0, 0);
+            } else {
+                int offsetX = 60;
+                int offsetY = 80;
             selectionMenu.addToComponent(requestComponent);
             requestInputContext = currentInputContext;
-            selectionMenu.show(requestComponent, 60, 80); // TODO: get proper x, y...
+                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;
+
         }
     }
 
     private String getCurrentSelection() {
         InputContext inputContext = currentInputContext;
< prev index next >