diff --git a/java/res/values-xlarge/dimens.xml b/java/res/values-xlarge/dimens.xml index 69283202e..11ad6b184 100644 --- a/java/res/values-xlarge/dimens.xml +++ b/java/res/values-xlarge/dimens.xml @@ -42,6 +42,7 @@ 24dip 6dip + 10.0mm 46dip 15.0mm diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index 7f00cdba3..90bf1bfad 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -46,6 +46,7 @@ -0.05in + 0.0mm 42dip 63dip diff --git a/java/src/com/android/inputmethod/latin/ClipTouchEventWindowCallback.java b/java/src/com/android/inputmethod/latin/ClipTouchEventWindowCallback.java new file mode 100644 index 000000000..d12c70075 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/ClipTouchEventWindowCallback.java @@ -0,0 +1,75 @@ +/* + * 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()); + } +} diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index bbe3f78f2..198d34f4a 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -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; @@ -569,6 +573,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"); } @@ -883,15 +895,13 @@ 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) { - // Check frame layout's visibility - if (fl.getVisibility() == View.INVISIBLE) { - y = fl.getHeight(); - height += y; - } else if (fl.getVisibility() == View.VISIBLE) { - height += fl.getHeight(); - } + final FrameLayout fl = (FrameLayout) candidateParent; + // Check frame layout's visibility + if (fl.getVisibility() == View.INVISIBLE) { + y = fl.getHeight(); + height += y; + } else if (fl.getVisibility() == View.VISIBLE) { + height += fl.getHeight(); } } } diff --git a/java/src/com/android/inputmethod/latin/WindowCallbackAdapter.java b/java/src/com/android/inputmethod/latin/WindowCallbackAdapter.java new file mode 100644 index 000000000..be9bb2bd8 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/WindowCallbackAdapter.java @@ -0,0 +1,168 @@ +/* + * 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; + } +}