mirror of
https://github.com/termux/termux-app
synced 2024-06-17 22:57:08 +00:00
Merge e42d3b30ab
into 2f40df91e5
This commit is contained in:
commit
9ab0270bff
|
@ -2,12 +2,9 @@ package com.termux.app.terminal;
|
|||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
|
@ -15,7 +12,6 @@ import android.view.MotionEvent;
|
|||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.termux.R;
|
||||
import com.termux.app.TermuxActivity;
|
||||
|
@ -216,6 +212,11 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase {
|
|||
return mActivity.getProperties().isEnforcingCharBasedInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInputComposingDisabled() {
|
||||
return mActivity.getProperties().isInputComposingDisabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUseCtrlSpaceWorkaround() {
|
||||
return mActivity.getProperties().isUsingCtrlSpaceWorkaround();
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package com.termux.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Editable;
|
||||
import android.text.Selection;
|
||||
import android.text.SpanWatcher;
|
||||
import android.text.Spannable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import com.termux.view.inputmethod.TerminalInputConnection;
|
||||
|
||||
class ChangeWatcher implements TextWatcher, SpanWatcher {
|
||||
final TerminalView mTerminalView;
|
||||
|
||||
ChangeWatcher(TerminalView terminalView) {
|
||||
this.mTerminalView = terminalView;
|
||||
}
|
||||
|
||||
private void sendUpdateSelection() {
|
||||
final InputMethodManager imm = (InputMethodManager) mTerminalView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
final Editable text = mTerminalView.getImeBuffer();
|
||||
if (imm != null && text != null) {
|
||||
final int selectionStart = Selection.getSelectionStart(text);
|
||||
final int selectionEnd = Selection.getSelectionEnd(text);
|
||||
|
||||
final int candStart = TerminalInputConnection.getComposingSpanStart(text);
|
||||
final int candEnd = TerminalInputConnection.getComposingSpanEnd(text);
|
||||
imm.updateSelection(mTerminalView, selectionStart, selectionEnd, candStart, candEnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void spanChange(Object what) {
|
||||
if (what == Selection.SELECTION_START || what == Selection.SELECTION_END) {
|
||||
sendUpdateSelection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpanAdded(Spannable text, Object what, int start, int end) {
|
||||
|
||||
spanChange(what);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSpanRemoved(Spannable text, Object what, int start, int end) {
|
||||
spanChange(what);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpanChanged(Spannable text, Object what, int ostart, int oend, int nstart, int nend) {
|
||||
spanChange(what);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
mTerminalView.invalidate();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.termux.view;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Typeface;
|
||||
|
@ -55,7 +56,8 @@ public final class TerminalRenderer {
|
|||
|
||||
/** Render the terminal to a canvas with at a specified row scroll, and an optional rectangular selection. */
|
||||
public final void render(TerminalEmulator mEmulator, Canvas canvas, int topRow,
|
||||
int selectionY1, int selectionY2, int selectionX1, int selectionX2) {
|
||||
int selectionY1, int selectionY2, int selectionX1, int selectionX2,
|
||||
CharSequence imeBuffer) {
|
||||
final boolean reverseVideo = mEmulator.isReverseVideo();
|
||||
final int endRow = topRow + mEmulator.mRows;
|
||||
final int columns = mEmulator.mColumns;
|
||||
|
@ -153,6 +155,12 @@ public final class TerminalRenderer {
|
|||
}
|
||||
drawTextRun(canvas, line, palette, heightOffset, lastRunStartColumn, columnWidthSinceLastRun, lastRunStartIndex, charsSinceLastRun,
|
||||
measuredWidthForRun, cursorColor, cursorShape, lastRunStyle, reverseVideo || invertCursorTextColor || lastRunInsideSelection);
|
||||
|
||||
if (row == cursorRow) {
|
||||
//ime fore color
|
||||
int imeFore = Color.DKGRAY;
|
||||
drawImeBuffer(canvas, heightOffset, cursorCol, mEmulator.mColors.mCurrentColors[TextStyle.COLOR_INDEX_CURSOR], imeFore, imeBuffer, columns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,6 +247,35 @@ public final class TerminalRenderer {
|
|||
if (savedMatrix) canvas.restore();
|
||||
}
|
||||
|
||||
private void drawImeBuffer(Canvas canvas, float y, int cursorX, int cursorColor, int imeFore, CharSequence imeBuffer, int columns) {
|
||||
// draw ime buffer
|
||||
final int bufLen = imeBuffer.length();
|
||||
if (bufLen > 0) {
|
||||
float cursorHeight = mFontLineSpacingAndAscent - mFontAscent;
|
||||
|
||||
final float left = cursorX * mFontWidth;
|
||||
final int maxWidth = (int) (columns * mFontWidth - left);
|
||||
if (maxWidth > 0) {
|
||||
final float[] widths = bufLen > asciiMeasures.length ? new float[bufLen] : asciiMeasures;
|
||||
|
||||
final int count = mTextPaint.getTextWidths(imeBuffer, 0, bufLen, widths);
|
||||
int offset = count - 1;
|
||||
int width = 0;
|
||||
for (; offset >= 0 && width < maxWidth; offset--) {
|
||||
width += widths[offset];
|
||||
}
|
||||
offset++;
|
||||
|
||||
mTextPaint.setColor(cursorColor);
|
||||
canvas.drawRect(left, y - cursorHeight, left + width,
|
||||
y, mTextPaint);
|
||||
|
||||
mTextPaint.setColor(imeFore);
|
||||
canvas.drawText(imeBuffer, offset, bufLen, left, y - mFontLineSpacingAndAscent, mTextPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float getFontWidth() {
|
||||
return mFontWidth;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import android.os.Looper;
|
|||
import android.os.SystemClock;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ActionMode;
|
||||
|
@ -39,6 +41,7 @@ import androidx.annotation.RequiresApi;
|
|||
import com.termux.terminal.KeyHandler;
|
||||
import com.termux.terminal.TerminalEmulator;
|
||||
import com.termux.terminal.TerminalSession;
|
||||
import com.termux.view.inputmethod.TerminalInputConnection;
|
||||
import com.termux.view.textselection.TextSelectionCursorController;
|
||||
|
||||
/** View displaying and interacting with a {@link TerminalSession}. */
|
||||
|
@ -95,6 +98,7 @@ public final class TerminalView extends View {
|
|||
|
||||
private static final String LOG_TAG = "TerminalView";
|
||||
|
||||
private final SpannableStringBuilder imeBuffer = new SpannableStringBuilder("");
|
||||
public TerminalView(Context context, AttributeSet attributes) { // NO_UCD (unused code)
|
||||
super(context, attributes);
|
||||
mGestureRecognizer = new GestureAndScaleRecognizer(context, new GestureAndScaleRecognizer.Listener() {
|
||||
|
@ -221,6 +225,11 @@ public final class TerminalView extends View {
|
|||
mScroller = new Scroller(context);
|
||||
AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
mAccessibilityEnabled = am.isEnabled();
|
||||
|
||||
|
||||
imeBuffer.setSpan(new ChangeWatcher(this),
|
||||
0, imeBuffer.length(),
|
||||
Spanned.SPAN_INCLUSIVE_INCLUSIVE | (100 << Spanned.SPAN_PRIORITY_SHIFT));
|
||||
}
|
||||
|
||||
|
||||
|
@ -265,8 +274,25 @@ public final class TerminalView extends View {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
public Editable getImeBuffer() {
|
||||
return imeBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||
if(!mClient.isInputComposingDisabled()){
|
||||
outAttrs.imeOptions =
|
||||
EditorInfo.IME_FLAG_NO_EXTRACT_UI |
|
||||
EditorInfo.IME_FLAG_NO_FULLSCREEN |
|
||||
EditorInfo.IME_FLAG_NO_ENTER_ACTION;
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
|
||||
outAttrs.hintText = "";
|
||||
outAttrs.initialSelStart = -1;
|
||||
outAttrs.initialSelEnd = -1;
|
||||
outAttrs.initialCapsMode = 0;
|
||||
return new TerminalInputConnection(this);
|
||||
}
|
||||
// Ensure that inputType is only set if TerminalView is selected view with the keyboard and
|
||||
// an alternate view is not selected, like an EditText. This is necessary if an activity is
|
||||
// initially started with the alternate view or if activity is returned to from another app
|
||||
|
@ -975,7 +1001,7 @@ public final class TerminalView extends View {
|
|||
mTextSelectionCursorController.getSelectors(sel);
|
||||
}
|
||||
|
||||
mRenderer.render(mEmulator, canvas, mTopRow, sel[0], sel[1], sel[2], sel[3]);
|
||||
mRenderer.render(mEmulator, canvas, mTopRow, sel[0], sel[1], sel[2], sel[3], imeBuffer);
|
||||
|
||||
// render the text selection handles
|
||||
renderTextSelection();
|
||||
|
|
|
@ -36,7 +36,7 @@ public interface TerminalViewClient {
|
|||
|
||||
boolean isTerminalViewSelected();
|
||||
|
||||
|
||||
boolean isInputComposingDisabled();
|
||||
|
||||
void copyModeChanged(boolean copyMode);
|
||||
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
|
||||
package com.termux.view.inputmethod;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.Selection;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.inputmethod.BaseInputConnection;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputContentInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.termux.terminal.TerminalEmulator;
|
||||
import com.termux.view.TerminalView;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class TerminalInputConnection extends BaseInputConnection {
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String TAG = "TerminalInputConnection";
|
||||
private final Editable editable;
|
||||
private final TerminalView mTargetView;
|
||||
|
||||
public TerminalInputConnection(TerminalView targetView) {
|
||||
super(targetView, true);
|
||||
mTargetView = targetView;
|
||||
|
||||
editable = targetView.getImeBuffer();
|
||||
editable.clear();
|
||||
Selection.setSelection(editable, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editable getEditable() {
|
||||
return editable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
if (DEBUG) Log.d(TAG, "commitText: " + text.length() + " " + text.getClass() + " ");
|
||||
//Some input methods convert the enter key to '\n', split it
|
||||
boolean sendEnter = false;
|
||||
final int last;
|
||||
if (text != null && (last = text.length() - 1) >= 0 && text.charAt(last) == '\n') {
|
||||
text = text.subSequence(0, last);
|
||||
sendEnter = true;
|
||||
}
|
||||
|
||||
super.commitText(text, newCursorPosition);
|
||||
|
||||
|
||||
final Editable editable = getEditable();
|
||||
|
||||
sendTextToTerminal(editable);
|
||||
|
||||
editable.clear();
|
||||
|
||||
if (sendEnter) {
|
||||
sendEnterKey();
|
||||
|
||||
try {
|
||||
// Simulate insert '\n', then clear()
|
||||
InputMethodManager imm = (InputMethodManager) mTargetView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
imm.updateSelection(mTargetView, 1, 1, -1, -1);
|
||||
imm.updateSelection(mTargetView, 0, 0, -1, -1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sendEnterKey() {
|
||||
sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
|
||||
sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
|
||||
if (DEBUG) Log.d(TAG, "getExtractedText: " + flags);
|
||||
final ExtractedText extract = new ExtractedText();
|
||||
final Editable editable = getEditable();
|
||||
extract.startOffset = 0;
|
||||
int a = Selection.getSelectionStart(editable);
|
||||
int b = Selection.getSelectionEnd(editable);
|
||||
if (a > b) {
|
||||
int tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
extract.selectionStart = a;
|
||||
extract.selectionEnd = b;
|
||||
extract.text = editable;
|
||||
return extract;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beginBatchEdit() {
|
||||
if (DEBUG) Log.d(TAG, "beginBatchEdit: ");
|
||||
return super.beginBatchEdit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean endBatchEdit() {
|
||||
if (DEBUG) Log.d(TAG, "endBatchEdit: ");
|
||||
return super.endBatchEdit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearMetaKeyStates(int states) {
|
||||
if (DEBUG) Log.d(TAG, "clearMetaKeyStates: ");
|
||||
return super.clearMetaKeyStates(states);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTextAfterCursor(int length, int flags) {
|
||||
if (DEBUG) Log.d(TAG, "getTextAfterCursor: " + length + " " + flags);
|
||||
return super.getTextAfterCursor(length, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTextBeforeCursor(int length, int flags) {
|
||||
if (DEBUG) Log.d(TAG, "getTextBeforeCursor: " + length + " " + flags);
|
||||
return super.getTextBeforeCursor(length, flags);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
if (DEBUG) Log.d(TAG, "setComposingText: " + text + " " + newCursorPosition);
|
||||
return super.setComposingText(text, newCursorPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingRegion(int start, int end) {
|
||||
if (DEBUG) Log.d(TAG, "setComposingRegion: " + start + " " + end);
|
||||
return super.setComposingRegion(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSelection(int start, int end) {
|
||||
if (DEBUG) Log.d(TAG, "setSelection: ");
|
||||
return super.setSelection(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int leftLength, int rightLength) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "deleteSurroundingText: " + leftLength + " " + rightLength);
|
||||
}
|
||||
return super.deleteSurroundingText(leftLength, rightLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendKeyEvent(KeyEvent event) {
|
||||
if (DEBUG) Log.d(TAG, "sendKeyEvent: " + event.getDisplayLabel());
|
||||
return super.sendKeyEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finishComposingText() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "finishComposingText: " + getEditable() + " " + getComposingSpanStart(getEditable()) + " " + getComposingSpanEnd(getEditable()));
|
||||
}
|
||||
super.finishComposingText();
|
||||
|
||||
final Editable editable = getEditable();
|
||||
sendTextToTerminal(editable);
|
||||
|
||||
editable.clear();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCursorCapsMode(int reqModes) {
|
||||
if (DEBUG) Log.d(TAG, "getCursorCapsMode: " + reqModes);
|
||||
return super.getCursorCapsMode(reqModes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitContent(@NonNull InputContentInfo inputContentInfo, int flags, Bundle opts) {
|
||||
if (DEBUG) Log.d(TAG, "commitContent: ");
|
||||
return super.commitContent(inputContentInfo, flags, opts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitCompletion(CompletionInfo text) {
|
||||
if (DEBUG) Log.d(TAG, "commitCompletion: " + text.getText());
|
||||
return super.commitCompletion(text);
|
||||
}
|
||||
|
||||
private void sendTextToTerminal(CharSequence text) {
|
||||
mTargetView.stopTextSelectionMode();
|
||||
final int textLengthInChars = text.length();
|
||||
for (int i = 0; i < textLengthInChars; i++) {
|
||||
char firstChar = text.charAt(i);
|
||||
int codePoint;
|
||||
if (Character.isHighSurrogate(firstChar)) {
|
||||
if (++i < textLengthInChars) {
|
||||
codePoint = Character.toCodePoint(firstChar, text.charAt(i));
|
||||
} else {
|
||||
// At end of string, with no low surrogate following the high:
|
||||
codePoint = TerminalEmulator.UNICODE_REPLACEMENT_CHAR;
|
||||
}
|
||||
} else {
|
||||
codePoint = firstChar;
|
||||
}
|
||||
|
||||
// Check onKeyDown() for details.
|
||||
if (mTargetView.mClient.readShiftKey())
|
||||
codePoint = Character.toUpperCase(codePoint);
|
||||
|
||||
boolean ctrlHeld = false;
|
||||
if (codePoint <= 31 && codePoint != 27) {
|
||||
if (codePoint == '\n') {
|
||||
// The AOSP keyboard and descendants seems to send \n as text when the enter key is pressed,
|
||||
// instead of a key event like most other keyboard apps. A terminal expects \r for the enter
|
||||
// key (although when icrnl is enabled this doesn't make a difference - run 'stty -icrnl' to
|
||||
// check the behaviour).
|
||||
codePoint = '\r';
|
||||
}
|
||||
|
||||
// E.g. penti keyboard for ctrl input.
|
||||
ctrlHeld = true;
|
||||
switch (codePoint) {
|
||||
case 31:
|
||||
codePoint = '_';
|
||||
break;
|
||||
case 30:
|
||||
codePoint = '^';
|
||||
break;
|
||||
case 29:
|
||||
codePoint = ']';
|
||||
break;
|
||||
case 28:
|
||||
codePoint = '\\';
|
||||
break;
|
||||
default:
|
||||
codePoint += 96;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mTargetView.inputCodePoint(TerminalView.KEY_EVENT_SOURCE_SOFT_KEYBOARD, codePoint, ctrlHeld, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -305,6 +305,8 @@ public class TextSelectionCursorController implements CursorController {
|
|||
}
|
||||
|
||||
private int getValidCurX(TerminalBuffer screen, int cy, int cx) {
|
||||
//Cursor drawing incompatible.
|
||||
/*
|
||||
String line = screen.getSelectedText(0, cy, cx, cy);
|
||||
if (!TextUtils.isEmpty(line)) {
|
||||
int col = 0;
|
||||
|
@ -332,6 +334,7 @@ public class TextSelectionCursorController implements CursorController {
|
|||
col = cend;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return cx;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ public class TextSelectionHandleView extends View {
|
|||
|
||||
private final int mInitialOrientation;
|
||||
private int mOrientation;
|
||||
private float mAdjHotspotOffsetX = 0;
|
||||
|
||||
public static final int LEFT = 0;
|
||||
public static final int RIGHT = 2;
|
||||
|
@ -149,7 +150,7 @@ public class TextSelectionHandleView extends View {
|
|||
|
||||
public void removeFromParent() {
|
||||
if (!isParentNull()) {
|
||||
((ViewGroup)this.getParent()).removeView(this);
|
||||
((ViewGroup) this.getParent()).removeView(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,10 +161,9 @@ public class TextSelectionHandleView extends View {
|
|||
}
|
||||
|
||||
private void moveTo(int x, int y, boolean forceOrientationCheck) {
|
||||
float oldHotspotX = mHotspotX;
|
||||
checkChangedOrientation(x, forceOrientationCheck);
|
||||
mPointX = (int) (x - (isShowing() ? oldHotspotX : mHotspotX));
|
||||
mPointX = (int) (x - mHotspotX);
|
||||
mPointY = y;
|
||||
checkChangedOrientation(forceOrientationCheck);
|
||||
|
||||
if (isPositionVisible()) {
|
||||
int[] coords = null;
|
||||
|
@ -198,11 +198,14 @@ public class TextSelectionHandleView extends View {
|
|||
|
||||
public void changeOrientation(int orientation) {
|
||||
if (mOrientation != orientation) {
|
||||
final float hotspotX = mHotspotX;
|
||||
setOrientation(orientation);
|
||||
mAdjHotspotOffsetX = (mHotspotX - hotspotX);
|
||||
mTouchToWindowOffsetX += mAdjHotspotOffsetX;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkChangedOrientation(int posX, boolean force) {
|
||||
private void checkChangedOrientation(boolean force) {
|
||||
if (!mIsDragging && !force) {
|
||||
return;
|
||||
}
|
||||
|
@ -231,6 +234,7 @@ public class TextSelectionHandleView extends View {
|
|||
if (parent == null || !parent.getChildVisibleRect(hostView, clip, null)) {
|
||||
return;
|
||||
}
|
||||
final int posX = (int) (mPointX + mAdjHotspotOffsetX);
|
||||
|
||||
if (posX - mHandleWidth < clip.left) {
|
||||
changeOrientation(RIGHT);
|
||||
|
@ -315,6 +319,7 @@ public class TextSelectionHandleView extends View {
|
|||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
mAdjHotspotOffsetX = 0;
|
||||
mIsDragging = false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -3,18 +3,13 @@ package com.termux.shared.termux.settings.properties;
|
|||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.termux.shared.termux.shell.am.TermuxAmSocketServer;
|
||||
import com.termux.shared.theme.NightMode;
|
||||
import com.termux.shared.file.FileUtils;
|
||||
import com.termux.shared.file.filesystem.FileType;
|
||||
import com.termux.shared.settings.properties.SharedProperties;
|
||||
import com.termux.shared.termux.TermuxConstants;
|
||||
import com.termux.shared.logger.Logger;
|
||||
import com.termux.terminal.TerminalEmulator;
|
||||
import com.termux.view.TerminalView;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
|
@ -121,6 +116,8 @@ public final class TermuxPropertyConstants {
|
|||
public static final String KEY_ENFORCE_CHAR_BASED_INPUT = "enforce-char-based-input"; // Default: "enforce-char-based-input"
|
||||
|
||||
|
||||
public static final String KEY_DISABLE_INPUT_COMPOSING = "disable-input-composing";
|
||||
|
||||
|
||||
/** Defines the key for whether text for the extra keys buttons should be all capitalized automatically */
|
||||
public static final String KEY_EXTRA_KEYS_TEXT_ALL_CAPS = "extra-keys-text-all-caps"; // Default: "extra-keys-text-all-caps"
|
||||
|
@ -396,6 +393,7 @@ public final class TermuxPropertyConstants {
|
|||
KEY_DISABLE_HARDWARE_KEYBOARD_SHORTCUTS,
|
||||
KEY_DISABLE_TERMINAL_SESSION_CHANGE_TOAST,
|
||||
KEY_ENFORCE_CHAR_BASED_INPUT,
|
||||
KEY_DISABLE_INPUT_COMPOSING,
|
||||
KEY_EXTRA_KEYS_TEXT_ALL_CAPS,
|
||||
KEY_HIDE_SOFT_KEYBOARD_ON_STARTUP,
|
||||
KEY_RUN_TERMUX_AM_SOCKET_SERVER,
|
||||
|
@ -459,7 +457,8 @@ public final class TermuxPropertyConstants {
|
|||
*/
|
||||
public static final Set<String> TERMUX_DEFAULT_TRUE_BOOLEAN_BEHAVIOUR_PROPERTIES_LIST = new HashSet<>(Arrays.asList(
|
||||
KEY_EXTRA_KEYS_TEXT_ALL_CAPS,
|
||||
KEY_RUN_TERMUX_AM_SOCKET_SERVER
|
||||
KEY_RUN_TERMUX_AM_SOCKET_SERVER,
|
||||
KEY_DISABLE_INPUT_COMPOSING
|
||||
));
|
||||
|
||||
/** Defines the set for keys loaded by termux that have default inverted boolean behaviour with false as default.
|
||||
|
|
|
@ -598,6 +598,10 @@ public abstract class TermuxSharedProperties {
|
|||
return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_ENFORCE_CHAR_BASED_INPUT, true);
|
||||
}
|
||||
|
||||
public boolean isInputComposingDisabled(){
|
||||
return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_DISABLE_INPUT_COMPOSING, true);
|
||||
}
|
||||
|
||||
public boolean shouldExtraKeysTextBeAllCaps() {
|
||||
return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_EXTRA_KEYS_TEXT_ALL_CAPS, true);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@ public class TermuxTerminalViewClientBase implements TerminalViewClient {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInputComposingDisabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean shouldUseCtrlSpaceWorkaround() {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user