Check embedded windows for IME target
When checking IME target, if the main window can't be IME target but the embedded window can be, the IME will not be z ordered correctly. The IME should be updated so it's z ordered to the embedded window. Since the embedded window is in a different display, we set the IME target to the host to avoid any issues with IME target being on a different display. Test: WindowStateTests#testCanWindowWithEmbeddedDisplayBeImeTarget Test: Host window with flag FLAG_NOT_FOCUSABLE and embedded without. IME can be shown for the embedded window Bug: 156785479 Change-Id: Id46dc8be16f1a00dd31d79cc61bfcb83a2515888
This commit is contained in:
@@ -2262,7 +2262,29 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
mHasSurface = hasSurface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether one of the Windows in a Display embedded in this Window can be an IME target.
|
||||
*/
|
||||
private boolean canWindowInEmbeddedDisplayBeImeTarget() {
|
||||
final int embeddedDisplayContentsSize = mEmbeddedDisplayContents.size();
|
||||
for (int i = embeddedDisplayContentsSize - 1; i >= 0; i--) {
|
||||
final DisplayContent edc = mEmbeddedDisplayContents.valueAt(i);
|
||||
if (edc.forAllWindows(WindowState::canBeImeTarget, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canBeImeTarget() {
|
||||
// If any of the embedded windows can be the IME target, this window will be the final IME
|
||||
// target. This is because embedded windows are on a different display in WM so it would
|
||||
// cause confusion trying to set the IME to a window on a different display. Instead, just
|
||||
// make the host window the IME target.
|
||||
if (canWindowInEmbeddedDisplayBeImeTarget()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mIsImWindow) {
|
||||
// IME windows can't be IME targets. IME targets are required to be below the IME
|
||||
// windows and that wouldn't be possible if the IME window is its own target...silly.
|
||||
|
||||
@@ -269,6 +269,26 @@ public class WindowStateTests extends WindowTestsBase {
|
||||
assertTrue(stack.shouldIgnoreInput());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanWindowWithEmbeddedDisplayBeImeTarget() {
|
||||
final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow");
|
||||
final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, "imeWindow");
|
||||
|
||||
imeWindow.setHasSurface(true);
|
||||
appWindow.setHasSurface(true);
|
||||
|
||||
appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
|
||||
assertFalse(appWindow.canBeImeTarget());
|
||||
|
||||
DisplayContent secondDisplay = createNewDisplay();
|
||||
final WindowState embeddedWindow = createWindow(null, TYPE_APPLICATION, secondDisplay,
|
||||
"embeddedWindow");
|
||||
appWindow.addEmbeddedDisplayContent(secondDisplay);
|
||||
embeddedWindow.setHasSurface(true);
|
||||
embeddedWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE;
|
||||
assertTrue(appWindow.canBeImeTarget());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWindow() {
|
||||
final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
|
||||
|
||||
Reference in New Issue
Block a user