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

Commit de59a840 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Implement callback to handle touch event outside SoftInputWindow

Bug: 3238092
Change-Id: Ie8d4469bc2c6880bdf2a0c4e4eec68bb136b837c
parent 156493cf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
    <dimen name="key_preview_text_size_large">24dip</dimen>
    <!-- left or right padding of label alignment -->
    <dimen name="key_label_horizontal_alignment_padding">6dip</dimen>
    <dimen name="keyboard_bottom_row_vertical_correction">10.0mm</dimen>

    <dimen name="candidate_strip_height">46dip</dimen>
    <dimen name="candidate_strip_padding">15.0mm</dimen>
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
    <!-- We use "inch", not "dip" because this value tries dealing with physical distance related
         to user's finger. -->
    <dimen name="keyboard_vertical_correction">-0.05in</dimen>
    <dimen name="keyboard_bottom_row_vertical_correction">0.0mm</dimen>

    <dimen name="candidate_strip_height">42dip</dimen>
    <dimen name="candidate_strip_fading_edge_length">63dip</dimen>
+75 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.android.inputmethod.latin;

import android.view.MotionEvent;
import android.view.View;
import android.view.Window;

public class ClipTouchEventWindowCallback extends WindowCallbackAdapter {
    private final View mDecorView;
    private final int mKeyboardBottomRowVerticalCorrection;

    public ClipTouchEventWindowCallback(Window window, int keyboardBottomRowVerticalCorrection) {
        super(window.getCallback());
        mDecorView = window.getDecorView();
        mKeyboardBottomRowVerticalCorrection = keyboardBottomRowVerticalCorrection;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent me) {
        final int height = mDecorView.getHeight();
        final MotionEvent event = clipMotionEvent(me, height,
                height + mKeyboardBottomRowVerticalCorrection);
        return super.dispatchTouchEvent(event);
    }

    private static MotionEvent clipMotionEvent(MotionEvent me, int minHeight, int maxHeight) {
        final int pointerCount = me.getPointerCount();
        boolean shouldClip = false;
        for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
            final float y = me.getY(pointerIndex);
            if (y >= minHeight && y < maxHeight) {
                shouldClip = true;
                break;
            }
        }
        if (!shouldClip)
            return me;

        if (pointerCount == 1) {
            me.setLocation(me.getX(), minHeight - 1);
            return me;
        }

        final int[] pointerIds = new int[pointerCount];
        final MotionEvent.PointerCoords[] pointerCoords =
                new MotionEvent.PointerCoords[pointerCount];
        for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
            pointerIds[pointerIndex] = me.getPointerId(pointerIndex);
            final MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
            me.getPointerCoords(pointerIndex, coords);
            pointerCoords[pointerIndex] = coords;
            if (coords.y >= minHeight && coords.y < maxHeight)
                coords.y = minHeight - 1;
        }
        return MotionEvent.obtain(
                me.getDownTime(), me.getEventTime(), me.getAction(), pointerCount, pointerIds,
                pointerCoords, me.getMetaState(), me.getXPrecision(), me.getYPrecision(),
                me.getDeviceId(), me.getEdgeFlags(), me.getSource(), me.getFlags());
    }
}
+19 −9
Original line number Diff line number Diff line
@@ -161,6 +161,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
    private int mConfigDelayBeforeFadeoutLanguageOnSpacebar;
    private int mConfigDurationOfFadeoutLanguageOnSpacebar;
    private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar;
    // For example, to deal with status bar on tablet.
    private int mKeyboardBottomRowVerticalCorrection;

    private int mCorrectionMode;
    private int mCommittedLength;
@@ -377,6 +379,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                R.integer.config_duration_of_fadeout_language_on_spacebar);
        mConfigFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger(
                R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f;
        mKeyboardBottomRowVerticalCorrection = (int)res.getDimension(
                R.dimen.keyboard_bottom_row_vertical_correction);

        Utils.GCUtils.getInstance().reset();
        boolean tryGC = true;
@@ -566,6 +570,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen

        mVoiceConnector.onStartInputView(inputView.getWindowToken());

        if (mKeyboardBottomRowVerticalCorrection > 0) {
            final Window window = getWindow().getWindow();
            if (!(window.getCallback() instanceof ClipTouchEventWindowCallback)) {
                window.setCallback(new ClipTouchEventWindowCallback(
                        window, mKeyboardBottomRowVerticalCorrection));
            }
        }

        if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
    }

@@ -880,8 +892,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
            if (mCandidateViewContainer != null) {
                ViewParent candidateParent = mCandidateViewContainer.getParent();
                if (candidateParent instanceof FrameLayout) {
                    FrameLayout fl = (FrameLayout) candidateParent;
                    if (fl != null) {
                    final FrameLayout fl = (FrameLayout) candidateParent;
                    // Check frame layout's visibility
                    if (fl.getVisibility() == View.INVISIBLE) {
                        y = fl.getHeight();
@@ -891,7 +902,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                    }
                }
            }
            }
            if (DEBUG) {
                Log.d(TAG, "Touchable region " + x + ", " + y + ", " + width + ", " + height);
            }
+168 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.android.inputmethod.latin;

import android.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityEvent;

public class WindowCallbackAdapter implements Window.Callback {
    private final Window.Callback mPreviousCallback;

    public WindowCallbackAdapter(Window.Callback previousCallback) {
        mPreviousCallback = previousCallback;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (mPreviousCallback != null)
            return mPreviousCallback.dispatchKeyEvent(event);
        return false;
    }

    @Override
    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
        if (mPreviousCallback != null)
            return mPreviousCallback.dispatchKeyShortcutEvent(event);
        return false;
    }

    @Override
    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
        if (mPreviousCallback != null)
            return mPreviousCallback.dispatchPopulateAccessibilityEvent(event);
        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (mPreviousCallback != null)
            return mPreviousCallback.dispatchTouchEvent(event);
        return false;
    }

    @Override
    public boolean dispatchTrackballEvent(MotionEvent event) {
        if (mPreviousCallback != null)
            return mPreviousCallback.dispatchTrackballEvent(event);
        return false;
    }

    @Override
    public void onActionModeFinished(ActionMode mode) {
        if (mPreviousCallback != null)
            mPreviousCallback.onActionModeFinished(mode);
    }

    @Override
    public void onActionModeStarted(ActionMode mode) {
        if (mPreviousCallback != null)
            mPreviousCallback.onActionModeStarted(mode);
    }

    @Override
    public void onAttachedToWindow() {
        if (mPreviousCallback != null)
            mPreviousCallback.onAttachedToWindow();
    }

    @Override
    public void onContentChanged() {
        if (mPreviousCallback != null)
            mPreviousCallback.onContentChanged();
    }

    @Override
    public boolean onCreatePanelMenu(int featureId, Menu menu) {
        if (mPreviousCallback != null)
            return mPreviousCallback.onCreatePanelMenu(featureId, menu);
        return false;
    }

    @Override
    public View onCreatePanelView(int featureId) {
        if (mPreviousCallback != null)
            return mPreviousCallback.onCreatePanelView(featureId);
        return null;
    }

    @Override
    public void onDetachedFromWindow() {
        if (mPreviousCallback != null)
            mPreviousCallback.onDetachedFromWindow();
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        if (mPreviousCallback != null)
            return mPreviousCallback.onMenuItemSelected(featureId, item);
        return false;
    }

    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        if (mPreviousCallback != null)
            return mPreviousCallback.onMenuOpened(featureId, menu);
        return false;
    }

    @Override
    public void onPanelClosed(int featureId, Menu menu) {
        if (mPreviousCallback != null)
            mPreviousCallback.onPanelClosed(featureId, menu);
    }

    @Override
    public boolean onPreparePanel(int featureId, View view, Menu menu) {
        if (mPreviousCallback != null)
            return mPreviousCallback.onPreparePanel(featureId, view, menu);
        return false;
    }

    @Override
    public boolean onSearchRequested() {
        if (mPreviousCallback != null)
            return mPreviousCallback.onSearchRequested();
        return false;
    }

    @Override
    public void onWindowAttributesChanged(LayoutParams attrs) {
        if (mPreviousCallback != null)
            mPreviousCallback.onWindowAttributesChanged(attrs);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        if (mPreviousCallback != null)
            mPreviousCallback.onWindowFocusChanged(hasFocus);
    }

    @Override
    public ActionMode onWindowStartingActionMode(Callback callback) {
        if (mPreviousCallback != null)
            return mPreviousCallback.onWindowStartingActionMode(callback);
        return null;
    }
}