JDK-8264728 : When use chinese IME, the candidate box isn't moved with caret of JTextArea
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt:i18n
  • Affected Version: 8,9,15,16
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: linux
  • CPU: x86_64
  • Submitted: 2021-03-31
  • Updated: 2024-07-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
LINUX

A DESCRIPTION OF THE PROBLEM :
When I use chinese IME, the candidate box isn't moved with caret of JTextArea. It always under the window.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1, Run the example code for test case.
2, Open chinese IME to input a chinese char.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
We hope the candidate box is moved with caret of JTextArea.
ACTUAL -
The candidate box is always under the window.

---------- BEGIN SOURCE ----------
public class TestManager
{
    private static void testTextArea()
    {
        JFrame frame = new JFrame();
        frame.setSize(1000, 600);
        
        JTextArea ta = new JTextArea();
        ta.setText("OFFICE");
        ta.setBounds(100, 100, 300, 300);
       
        frame.getContentPane().setLayout(null);
        frame.getContentPane().add(ta);
        
        frame.setVisible(true);
    }

    
    public static void main(String[] args)
    {
    	testTextArea();
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
1, add code to XInputMethod
public class XInputMethod extends X11InputMethod {

    @Override
    public void setInputMethodContext(InputMethodContext context) {
        this.inputContext = context; // add this.
        context.enableClientWindowNotification(this, true);
    }
    public void dispatchEvent(AWTEvent e) {
        switch (e.getID())
        {
            case KeyEvent.KEY_PRESSED:
            case KeyEvent.KEY_RELEASED:
            case MouseEvent.MOUSE_CLICKED:
                positionCandidateWindow();
                break;

            default:
                break;
        }
    }


    private void positionCandidateWindow()
    {
        if (this.inputContext == null)
        {
            return;
        }

        Component client = getClientComponent();

        if (client == null || !client.isShowing())
        {
            return;
        }

        int x = 0;
        int y = 0;

        // Get this textcomponent coordinate from root window.
        Component temp = client;
        while (temp != null)
        {
             Component parent = temp.getParent();
             if (parent == null
                || temp instanceof javax.swing.JFrame
                || temp instanceof javax.swing.JDialog)
             {
                 break;
             }

             x += temp.getX();
             y += temp.getY();
             temp = parent;
        }

        if (haveActiveClient())
        {
            Rectangle rc = inputContext.getTextLocation(TextHitInfo.leading(0));
            x += rc.x;
            y += rc.y + rc.height;
            //we don't need this location
            Point p = client.getLocationOnScreen();
            x -= p.x;
            y -= p.y;
        }
        else
        {
            Dimension size = client.getSize();
            y += size.height;
        }

        moveCandidateWindow(x, y);
    }
private native void moveCandidateWindow(int x, int y);

2. add code to awt_InputMethod.c
JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_moveCandidateWindow
 (JNIEnv *env, jobject this, jint x, jint y)
{
    X11InputMethodData *pX11IMData;
    XVaNestedList preedit_attr;
    XPoint nspot;
    nspot.x = x;
    nspot.y = y;

    AWT_LOCK();
    pX11IMData = getX11InputMethodData(env, this);

    if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
        AWT_UNLOCK();
        return;
    }

    preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &nspot, NULL);
    XSetICValues(pX11IMData->current_ic, XNPreeditAttributes, preedit_attr, NULL);

    XFree(preedit_attr);

    AWT_UNLOCK();
}

3. add code to mapfile-vers
Java_sun_awt_X11_XInputMethod_moveCandidateWindow;

FREQUENCY : always



Comments
A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/13055 Date: 2023-03-16 06:06:50 +0000
09-07-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk8u-dev/pull/281 Date: 2023-03-10 00:51:37 +0000
10-03-2023

Checked with attached testcase in Ubuntu 20.04, with Chinese IME, issue is reproducible, attached screenshot for reference. Test Result: ========= 8: Fail 8u281: Fail JDK 15: Fail JDK 16: Fail JDK 17ea: Fail
05-04-2021