Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8264728: When use chinese IME, the candidate box isn't moved with caret of JTextArea #13055

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
25 changes: 25 additions & 0 deletions src/java.desktop/aix/native/libawt_xawt/awt/awt_InputMethod.c
Expand Up @@ -2250,3 +2250,28 @@ JNIEXPORT void JNICALL Java_sun_awt_X11InputMethod_setStatusAreaVisible
}
return;
}

JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_moveCandidateWindow
(JNIEnv *env, jobject this, jint x, jint y)
{
X11InputMethodData *pX11IMData;
XVaNestedList preedit_attr;
XPoint nspot;

AWT_LOCK();

pX11IMData = getX11InputMethodData(env, this);
if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
AWT_UNLOCK();
return;
}

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

XFree(preedit_attr);

AWT_UNLOCK();
}
87 changes: 87 additions & 0 deletions src/java.desktop/unix/classes/sun/awt/X11/XInputMethod.java
Expand Up @@ -25,10 +25,17 @@

package sun.awt.X11;

import java.awt.AWTEvent;
import java.awt.AWTException;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.font.TextHitInfo;
import java.awt.im.spi.InputMethodContext;
import java.awt.peer.ComponentPeer;

Expand All @@ -45,25 +52,35 @@
public class XInputMethod extends X11InputMethod {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XInputMethod");

private InputMethodContext inputContext;

public XInputMethod() throws AWTException {
super();
}

@Override
public void setInputMethodContext(InputMethodContext context) {
this.inputContext = context;
context.enableClientWindowNotification(this, true);
}

@Override
public void notifyClientWindowChange(Rectangle location) {
XComponentPeer peer = (XComponentPeer)getPeer(clientComponentWindow);
if (peer != null) {
adjustStatusWindow(peer.getContentWindow());
}

//After window moved, this would called.
positionCandidateWindow();
}

@Override
protected boolean openXIM() {
return openXIMNative(XToolkit.getDisplay());
}

@Override
protected boolean createXIC() {
XComponentPeer peer = (XComponentPeer)getPeer(clientComponentWindow);
if (peer == null) {
Expand All @@ -75,6 +92,7 @@

private static volatile long xicFocus;

@Override
protected void setXICFocus(ComponentPeer peer,
boolean value, boolean active) {
if (peer == null) {
Expand All @@ -93,6 +111,7 @@
/* XAWT_HACK FIX ME!
do NOT call client code!
*/
@Override
protected Container getParent(Component client) {
return client.getParent();
}
Expand All @@ -101,6 +120,7 @@
* Returns peer of the given client component. If the given client component
* doesn't have peer, peer of the native container of the client is returned.
*/
@Override
protected ComponentPeer getPeer(Component client) {
XComponentPeer peer;

Expand All @@ -126,15 +146,18 @@
* Subclasses should override disposeImpl() instead of dispose(). Client
* code should always invoke dispose(), never disposeImpl().
*/
@Override
protected synchronized void disposeImpl() {
super.disposeImpl();
clientComponentWindow = null;
}

@Override
protected void awtLock() {
XToolkit.awtLock();
}

@Override
protected void awtUnlock() {
XToolkit.awtUnlock();
}
Expand All @@ -145,6 +168,69 @@
return peer.getContentWindow();
}

@Override
public void dispatchEvent(AWTEvent e) {
switch (e.getID()) {
case KeyEvent.KEY_PRESSED:
case KeyEvent.KEY_RELEASED:
case MouseEvent.MOUSE_CLICKED:
positionCandidateWindow();
break;

default:
break;
}

super.dispatchEvent(e);

Check failure on line 184 in src/java.desktop/unix/classes/sun/awt/X11/XInputMethod.java

View check run for this annotation

openjdk / jcheck-openjdk/jdk-13055

Whitespace error

Column 0: tab Column 1: tab
}

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) {
break;
}

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

// Dialog has a parent, no use.
if (parent instanceof Window) {
break;
}
temp = parent;
}

if (haveActiveClient()) {
Rectangle rc = inputContext.getTextLocation(TextHitInfo.leading(0));
x += rc.x;
y += rc.y + rc.height;

Point p = client.getLocationOnScreen();
x -= p.x;
y -= p.y;
} else {
Dimension size = client.getSize();
y += size.height;
}

moveCandidateWindow(x, y);
}

/*
* Native methods
*/
Expand All @@ -153,4 +239,5 @@
private native void setXICFocusNative(long window,
boolean value, boolean active);
private native void adjustStatusWindow(long window);
private native void moveCandidateWindow(int x, int y);
}
27 changes: 26 additions & 1 deletion src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c
Expand Up @@ -865,7 +865,7 @@ createXIC(JNIEnv * env, X11InputMethodData *pX11IMData, Window w)
XVaNestedList preedit = NULL;
XVaNestedList status = NULL;
XIMStyle on_the_spot_styles = XIMPreeditCallbacks,
active_styles = 0,
active_styles = ROOT_WINDOW_STYLES,
passive_styles = 0,
no_styles = 0;
XIMCallback *callbacks;
Expand Down Expand Up @@ -1732,3 +1732,28 @@ static Window getParentWindow(Window w)
return parent;
}
#endif

JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_moveCandidateWindow
(JNIEnv *env, jobject this, jint x, jint y)
{
X11InputMethodData *pX11IMData;
XVaNestedList preedit_attr;
XPoint nspot;

AWT_LOCK();

pX11IMData = getX11InputMethodData(env, this);
if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
AWT_UNLOCK();
return;
}

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

XFree(preedit_attr);

AWT_UNLOCK();
}