Fix: Crash when click context menu too fast.
This commit is contained in:
@ -17,8 +17,8 @@ android {
|
|||||||
applicationId "io.neoterm"
|
applicationId "io.neoterm"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 5
|
versionCode 6
|
||||||
versionName "1.1.3"
|
versionName "1.1.4"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
resConfigs "zh"
|
resConfigs "zh"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
|
@ -10,14 +10,12 @@
|
|||||||
<application
|
<application
|
||||||
android:name=".App"
|
android:name=".App"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
android:fullBackupContent="@xml/backup_config"
|
||||||
android:extractNativeLibs="true"
|
android:extractNativeLibs="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity
|
|
||||||
android:name=".ui.setup.SetupActivity"
|
|
||||||
android:theme="@style/AppTheme.NoActionBar" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.NeoTermActivity"
|
android:name=".ui.NeoTermActivity"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
@ -31,6 +29,9 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".ui.setup.SetupActivity"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.pm.PackageManagerActivity"
|
android:name=".ui.pm.PackageManagerActivity"
|
||||||
android:label="@string/package_settings"
|
android:label="@string/package_settings"
|
||||||
@ -50,9 +51,21 @@
|
|||||||
android:name=".ui.settings.UISettingsActivity"
|
android:name=".ui.settings.UISettingsActivity"
|
||||||
android:theme="@style/Theme.AppCompat" />
|
android:theme="@style/Theme.AppCompat" />
|
||||||
|
|
||||||
|
<activity-alias
|
||||||
|
android:name=".NeoLotMainActivity"
|
||||||
|
android:targetActivity="io.neoterm.ui.NeoTermActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.IOT_LAUNCHER"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity-alias>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".services.NeoTermService"
|
android:name=".services.NeoTermService"
|
||||||
android:enabled="true" />
|
android:enabled="true" />
|
||||||
|
|
||||||
|
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
@ -421,8 +421,14 @@ public final class TerminalEmulator {
|
|||||||
if (codePoint >= 0x80 && codePoint <= 0x9F) {
|
if (codePoint >= 0x80 && codePoint <= 0x9F) {
|
||||||
// Sequence decoded to a C1 control character which is the same as escape followed by
|
// Sequence decoded to a C1 control character which is the same as escape followed by
|
||||||
// ((code & 0x7F) + 0x40).
|
// ((code & 0x7F) + 0x40).
|
||||||
processCodePoint(/* escape (hexadecimal=0x1B, octal=033): */27);
|
// processCodePoint(/* escape (hexadecimal=0x1B, octal=033): */27);
|
||||||
processCodePoint((codePoint & 0x7F) + 0x40);
|
// processCodePoint((codePoint & 0x7F) + 0x40);
|
||||||
|
|
||||||
|
// Sequence decoded to a C1 control character which we ignore. They are
|
||||||
|
// not used nowadays and increases the risk of messing up the terminal state
|
||||||
|
// on binary input. XTerm does not allow them in utf-8:
|
||||||
|
// "It is not possible to use a C1 control obtained from decoding the
|
||||||
|
// UTF-8 text" - http://invisible-island.net/xterm/ctlseqs/ctlseqs.htm
|
||||||
} else {
|
} else {
|
||||||
switch (Character.getType(codePoint)) {
|
switch (Character.getType(codePoint)) {
|
||||||
case Character.UNASSIGNED:
|
case Character.UNASSIGNED:
|
||||||
|
@ -114,7 +114,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference
|
|||||||
TabSwitcher.setupWithMenu(tabSwitcher, toolbar.menu, View.OnClickListener {
|
TabSwitcher.setupWithMenu(tabSwitcher, toolbar.menu, View.OnClickListener {
|
||||||
val imm = this@NeoTermActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
val imm = this@NeoTermActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
if (!tabSwitcher.isSwitcherShown) {
|
if (!tabSwitcher.isSwitcherShown) {
|
||||||
if (imm.isActive) {
|
if (imm.isActive && tabSwitcher.selectedTab is TermTab) {
|
||||||
val tab = tabSwitcher.selectedTab as TermTab
|
val tab = tabSwitcher.selectedTab as TermTab
|
||||||
tab.hideIme()
|
tab.hideIme()
|
||||||
}
|
}
|
||||||
|
@ -68,10 +68,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen
|
|||||||
.setTitle(model.packageInfo.packageName)
|
.setTitle(model.packageInfo.packageName)
|
||||||
.setMessage(model.getPackageDetails(this@PackageManagerActivity))
|
.setMessage(model.getPackageDetails(this@PackageManagerActivity))
|
||||||
.setPositiveButton(R.string.install, { _, _ ->
|
.setPositiveButton(R.string.install, { _, _ ->
|
||||||
TerminalDialog(this@PackageManagerActivity)
|
installPackage(model.packageInfo.packageName)
|
||||||
.execute(NeoTermPath.APT_BIN_PATH,
|
|
||||||
arrayOf("apt", "install", "-y", model.packageInfo.packageName!!))
|
|
||||||
.show("Installing ${model.packageInfo.packageName}")
|
|
||||||
})
|
})
|
||||||
.setNegativeButton(android.R.string.no, null)
|
.setNegativeButton(android.R.string.no, null)
|
||||||
.show()
|
.show()
|
||||||
@ -89,6 +86,20 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen
|
|||||||
refreshPackageList()
|
refreshPackageList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun installPackage(packageName: String?) {
|
||||||
|
if (packageName != null) {
|
||||||
|
TerminalDialog(this@PackageManagerActivity)
|
||||||
|
.execute(NeoTermPath.APT_BIN_PATH,
|
||||||
|
arrayOf("apt", "install", "-y", packageName))
|
||||||
|
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
||||||
|
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
||||||
|
dialog.setTitle(getString(R.string.done))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.show("Installing $packageName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
menuInflater.inflate(R.menu.menu_pm, menu)
|
menuInflater.inflate(R.menu.menu_pm, menu)
|
||||||
val searchItem = menu!!.findItem(R.id.action_search)
|
val searchItem = menu!!.findItem(R.id.action_search)
|
||||||
@ -170,6 +181,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen
|
|||||||
TerminalDialog(this@PackageManagerActivity)
|
TerminalDialog(this@PackageManagerActivity)
|
||||||
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
||||||
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
||||||
|
dialog.dismiss()
|
||||||
refreshPackageList()
|
refreshPackageList()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -4,6 +4,7 @@ import android.app.AlertDialog
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v7.app.AppCompatPreferenceActivity
|
import android.support.v7.app.AppCompatPreferenceActivity
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.widget.Toast
|
||||||
import io.neoterm.R
|
import io.neoterm.R
|
||||||
import io.neoterm.backend.TerminalSession
|
import io.neoterm.backend.TerminalSession
|
||||||
import io.neoterm.preference.NeoPreference
|
import io.neoterm.preference.NeoPreference
|
||||||
@ -39,9 +40,11 @@ class UISettingsActivity : AppCompatPreferenceActivity() {
|
|||||||
TerminalDialog(this)
|
TerminalDialog(this)
|
||||||
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
||||||
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
||||||
dialog.dismiss()
|
|
||||||
if (finishedSession?.exitStatus == 0) {
|
if (finishedSession?.exitStatus == 0) {
|
||||||
|
dialog.dismiss()
|
||||||
NeoPreference.store(R.string.key_general_shell, "zsh")
|
NeoPreference.store(R.string.key_general_shell, "zsh")
|
||||||
|
} else {
|
||||||
|
dialog.setTitle(getString(R.string.error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package io.neoterm.ui.setup
|
package io.neoterm.ui.setup
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.content.ContextCompat
|
import android.support.v4.content.ContextCompat
|
||||||
import android.support.v7.app.AlertDialog
|
import android.support.v7.app.AlertDialog
|
||||||
@ -63,11 +62,17 @@ class SetupActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TerminalDialog(this@SetupActivity)
|
TerminalDialog(this@SetupActivity)
|
||||||
.onDismiss(DialogInterface.OnCancelListener {
|
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
||||||
if (withShell != null) {
|
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
||||||
NeoPreference.store(R.string.key_general_shell, withShell!!)
|
if (finishedSession?.exitStatus == 0) {
|
||||||
|
dialog.dismiss()
|
||||||
|
if (withShell != null) {
|
||||||
|
NeoPreference.store(R.string.key_general_shell, withShell!!)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dialog.setTitle(getString(R.string.error))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finish()
|
|
||||||
})
|
})
|
||||||
.execute(NeoTermPath.APT_BIN_PATH, packageList.toTypedArray())
|
.execute(NeoTermPath.APT_BIN_PATH, packageList.toTypedArray())
|
||||||
.show(getString(R.string.installer_message))
|
.show(getString(R.string.installer_message))
|
||||||
@ -106,11 +111,13 @@ class SetupActivity : AppCompatActivity() {
|
|||||||
TerminalDialog(this)
|
TerminalDialog(this)
|
||||||
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
||||||
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
||||||
dialog.dismiss()
|
|
||||||
nextButton.visibility = View.VISIBLE
|
nextButton.visibility = View.VISIBLE
|
||||||
val exit = finishedSession?.exitStatus ?: 1
|
val exit = finishedSession?.exitStatus ?: 1
|
||||||
if (exit == 0) {
|
if (exit == 0) {
|
||||||
|
dialog.dismiss()
|
||||||
aptUpdated = true
|
aptUpdated = true
|
||||||
|
} else {
|
||||||
|
dialog.setTitle(getString(R.string.error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -66,6 +66,11 @@ class TerminalDialog(val context: Context) {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setTitle(title: String?) : TerminalDialog {
|
||||||
|
dialog?.setTitle(title)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
fun onFinish(finishedCallback: SessionFinishedCallback):TerminalDialog {
|
fun onFinish(finishedCallback: SessionFinishedCallback):TerminalDialog {
|
||||||
this.sessionFinishedCallback = finishedCallback
|
this.sessionFinishedCallback = finishedCallback
|
||||||
return this
|
return this
|
||||||
|
@ -36,22 +36,32 @@ import io.neoterm.backend.TerminalBuffer;
|
|||||||
import io.neoterm.backend.TerminalEmulator;
|
import io.neoterm.backend.TerminalEmulator;
|
||||||
import io.neoterm.backend.TerminalSession;
|
import io.neoterm.backend.TerminalSession;
|
||||||
|
|
||||||
/** View displaying and interacting with a {@link TerminalSession}. */
|
/**
|
||||||
|
* View displaying and interacting with a {@link TerminalSession}.
|
||||||
|
*/
|
||||||
public final class TerminalView extends View {
|
public final class TerminalView extends View {
|
||||||
|
|
||||||
/** Log view key and IME events. */
|
/**
|
||||||
|
* Log view key and IME events.
|
||||||
|
*/
|
||||||
private static final boolean LOG_KEY_EVENTS = false;
|
private static final boolean LOG_KEY_EVENTS = false;
|
||||||
|
|
||||||
/** The currently displayed terminal session, whose emulator is {@link #mEmulator}. */
|
/**
|
||||||
|
* The currently displayed terminal session, whose emulator is {@link #mEmulator}.
|
||||||
|
*/
|
||||||
TerminalSession mTermSession;
|
TerminalSession mTermSession;
|
||||||
/** Our terminal emulator whose session is {@link #mTermSession}. */
|
/**
|
||||||
|
* Our terminal emulator whose session is {@link #mTermSession}.
|
||||||
|
*/
|
||||||
TerminalEmulator mEmulator;
|
TerminalEmulator mEmulator;
|
||||||
|
|
||||||
TerminalRenderer mRenderer;
|
TerminalRenderer mRenderer;
|
||||||
|
|
||||||
TerminalViewClient mClient;
|
TerminalViewClient mClient;
|
||||||
|
|
||||||
/** The top row of text to display. Ranges from -activeTranscriptRows to 0. */
|
/**
|
||||||
|
* The top row of text to display. Ranges from -activeTranscriptRows to 0.
|
||||||
|
*/
|
||||||
int mTopRow;
|
int mTopRow;
|
||||||
|
|
||||||
boolean mIsSelectingText = false, mIsDraggingLeftSelection, mInitialTextSelection;
|
boolean mIsSelectingText = false, mIsDraggingLeftSelection, mInitialTextSelection;
|
||||||
@ -63,17 +73,25 @@ public final class TerminalView extends View {
|
|||||||
float mScaleFactor = 1.f;
|
float mScaleFactor = 1.f;
|
||||||
/* final */ GestureAndScaleRecognizer mGestureRecognizer;
|
/* final */ GestureAndScaleRecognizer mGestureRecognizer;
|
||||||
|
|
||||||
/** Keep track of where mouse touch event started which we report as mouse scroll. */
|
/**
|
||||||
|
* Keep track of where mouse touch event started which we report as mouse scroll.
|
||||||
|
*/
|
||||||
private int mMouseScrollStartX = -1, mMouseScrollStartY = -1;
|
private int mMouseScrollStartX = -1, mMouseScrollStartY = -1;
|
||||||
/** Keep track of the time when a touch event leading to sending mouse scroll events started. */
|
/**
|
||||||
|
* Keep track of the time when a touch event leading to sending mouse scroll events started.
|
||||||
|
*/
|
||||||
private long mMouseStartDownTime = -1;
|
private long mMouseStartDownTime = -1;
|
||||||
|
|
||||||
/* final */ Scroller mScroller;
|
/* final */ Scroller mScroller;
|
||||||
|
|
||||||
/** What was left in from scrolling movement. */
|
/**
|
||||||
|
* What was left in from scrolling movement.
|
||||||
|
*/
|
||||||
float mScrollRemainder;
|
float mScrollRemainder;
|
||||||
|
|
||||||
/** If non-zero, this is the last unicode code point received if that was a combining character. */
|
/**
|
||||||
|
* If non-zero, this is the last unicode code point received if that was a combining character.
|
||||||
|
*/
|
||||||
int mCombiningAccent;
|
int mCombiningAccent;
|
||||||
int mTextSize;
|
int mTextSize;
|
||||||
|
|
||||||
@ -429,7 +447,9 @@ public final class TerminalView extends View {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send a single mouse event code to the terminal. */
|
/**
|
||||||
|
* Send a single mouse event code to the terminal.
|
||||||
|
*/
|
||||||
void sendMouseEventCode(MotionEvent e, int button, boolean pressed) {
|
void sendMouseEventCode(MotionEvent e, int button, boolean pressed) {
|
||||||
int x = (int) (e.getX() / mRenderer.mFontWidth) + 1;
|
int x = (int) (e.getX() / mRenderer.mFontWidth) + 1;
|
||||||
int y = (int) ((e.getY() - mRenderer.mFontLineSpacingAndAscent) / mRenderer.mFontLineSpacing) + 1;
|
int y = (int) ((e.getY() - mRenderer.mFontLineSpacingAndAscent) / mRenderer.mFontLineSpacing) + 1;
|
||||||
@ -446,7 +466,9 @@ public final class TerminalView extends View {
|
|||||||
mEmulator.sendMouseEvent(button, x, y, pressed);
|
mEmulator.sendMouseEvent(button, x, y, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Perform a scroll, either from dragging the screen or by scrolling a mouse wheel. */
|
/**
|
||||||
|
* Perform a scroll, either from dragging the screen or by scrolling a mouse wheel.
|
||||||
|
*/
|
||||||
void doScroll(MotionEvent event, int rowsDown) {
|
void doScroll(MotionEvent event, int rowsDown) {
|
||||||
boolean up = rowsDown < 0;
|
boolean up = rowsDown < 0;
|
||||||
int amount = Math.abs(rowsDown);
|
int amount = Math.abs(rowsDown);
|
||||||
@ -464,7 +486,9 @@ public final class TerminalView extends View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Overriding {@link View#onGenericMotionEvent(MotionEvent)}. */
|
/**
|
||||||
|
* Overriding {@link View#onGenericMotionEvent(MotionEvent)}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onGenericMotionEvent(MotionEvent event) {
|
public boolean onGenericMotionEvent(MotionEvent event) {
|
||||||
if (mEmulator != null && event.isFromSource(InputDevice.SOURCE_MOUSE) && event.getAction() == MotionEvent.ACTION_SCROLL) {
|
if (mEmulator != null && event.isFromSource(InputDevice.SOURCE_MOUSE) && event.getAction() == MotionEvent.ACTION_SCROLL) {
|
||||||
@ -656,7 +680,7 @@ public final class TerminalView extends View {
|
|||||||
void inputCodePoint(int codePoint, boolean controlDownFromEvent, boolean leftAltDownFromEvent) {
|
void inputCodePoint(int codePoint, boolean controlDownFromEvent, boolean leftAltDownFromEvent) {
|
||||||
if (LOG_KEY_EVENTS) {
|
if (LOG_KEY_EVENTS) {
|
||||||
Log.i(EmulatorDebug.LOG_TAG, "inputCodePoint(codePoint=" + codePoint + ", controlDownFromEvent=" + controlDownFromEvent + ", leftAltDownFromEvent="
|
Log.i(EmulatorDebug.LOG_TAG, "inputCodePoint(codePoint=" + codePoint + ", controlDownFromEvent=" + controlDownFromEvent + ", leftAltDownFromEvent="
|
||||||
+ leftAltDownFromEvent + ")");
|
+ leftAltDownFromEvent + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean controlDown = controlDownFromEvent || mClient.readControlKey();
|
final boolean controlDown = controlDownFromEvent || mClient.readControlKey();
|
||||||
@ -709,7 +733,9 @@ public final class TerminalView extends View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Input the specified keyCode if applicable and return if the input was consumed. */
|
/**
|
||||||
|
* Input the specified keyCode if applicable and return if the input was consumed.
|
||||||
|
*/
|
||||||
public boolean handleKeyCode(int keyCode, int keyMod) {
|
public boolean handleKeyCode(int keyCode, int keyMod) {
|
||||||
TerminalEmulator term = mTermSession.getEmulator();
|
TerminalEmulator term = mTermSession.getEmulator();
|
||||||
String code = KeyHandler.getCode(keyCode, keyMod, term.isCursorKeysApplicationMode(), term.isKeypadApplicationMode());
|
String code = KeyHandler.getCode(keyCode, keyMod, term.isCursorKeysApplicationMode(), term.isKeypadApplicationMode());
|
||||||
@ -751,7 +777,9 @@ public final class TerminalView extends View {
|
|||||||
updateSize();
|
updateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check if the terminal size in rows and columns should be updated. */
|
/**
|
||||||
|
* Check if the terminal size in rows and columns should be updated.
|
||||||
|
*/
|
||||||
public void updateSize() {
|
public void updateSize() {
|
||||||
int viewWidth = getWidth();
|
int viewWidth = getWidth();
|
||||||
int viewHeight = getHeight();
|
int viewHeight = getHeight();
|
||||||
@ -795,7 +823,9 @@ public final class TerminalView extends View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Toggle text selection mode in the view. */
|
/**
|
||||||
|
* Toggle text selection mode in the view.
|
||||||
|
*/
|
||||||
@TargetApi(23)
|
@TargetApi(23)
|
||||||
public void toggleSelectingText(MotionEvent ev) {
|
public void toggleSelectingText(MotionEvent ev) {
|
||||||
mIsSelectingText = !mIsSelectingText;
|
mIsSelectingText = !mIsSelectingText;
|
||||||
@ -851,6 +881,11 @@ public final class TerminalView extends View {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||||
|
if (!mIsSelectingText) {
|
||||||
|
// Fix issue where the dialog is pressed while being dismissed.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case 1:
|
case 1:
|
||||||
String selectedText = mEmulator.getSelectedText(mSelX1, mSelY1, mSelX2, mSelY2).trim();
|
String selectedText = mEmulator.getSelectedText(mSelX1, mSelY1, mSelX2, mSelY2).trim();
|
||||||
|
5
app/src/main/res/xml/backup_config.xml
Normal file
5
app/src/main/res/xml/backup_config.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<full-backup-content>
|
||||||
|
<!-- See https://developer.android.com/training/backup/autosyncapi.html -->
|
||||||
|
<include domain="file" path="home/auto_backup" />
|
||||||
|
</full-backup-content>
|
Reference in New Issue
Block a user