Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 50dbc983 authored by chaviw's avatar chaviw
Browse files

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
parent f13d436c
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -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.
+20 −0
Original line number Diff line number Diff line
@@ -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");