From c9de9541bf1a51a339b0041e51a6e614c83cb5df Mon Sep 17 00:00:00 2001 From: zt515 Date: Sat, 8 Jul 2017 00:23:43 +0800 Subject: [PATCH] Fix: Crash when click context menu too fast. --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 19 +++++- .../io/neoterm/backend/TerminalEmulator.java | 10 ++- .../java/io/neoterm/ui/NeoTermActivity.kt | 2 +- .../neoterm/ui/pm/PackageManagerActivity.kt | 20 ++++-- .../neoterm/ui/settings/UISettingsActivity.kt | 5 +- .../java/io/neoterm/ui/setup/SetupActivity.kt | 19 ++++-- .../java/io/neoterm/view/TerminalDialog.kt | 5 ++ .../java/io/neoterm/view/TerminalView.java | 67 ++++++++++++++----- app/src/main/res/xml/backup_config.xml | 5 ++ 10 files changed, 121 insertions(+), 35 deletions(-) create mode 100644 app/src/main/res/xml/backup_config.xml diff --git a/app/build.gradle b/app/build.gradle index da71a2b..a798251 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,8 +17,8 @@ android { applicationId "io.neoterm" minSdkVersion 21 targetSdkVersion 25 - versionCode 5 - versionName "1.1.3" + versionCode 6 + versionName "1.1.4" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" resConfigs "zh" externalNativeBuild { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ffb2263..f5c6cae 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,14 +10,12 @@ - + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/backend/TerminalEmulator.java b/app/src/main/java/io/neoterm/backend/TerminalEmulator.java index a73f87a..32e3ef1 100755 --- a/app/src/main/java/io/neoterm/backend/TerminalEmulator.java +++ b/app/src/main/java/io/neoterm/backend/TerminalEmulator.java @@ -421,8 +421,14 @@ public final class TerminalEmulator { if (codePoint >= 0x80 && codePoint <= 0x9F) { // Sequence decoded to a C1 control character which is the same as escape followed by // ((code & 0x7F) + 0x40). - processCodePoint(/* escape (hexadecimal=0x1B, octal=033): */27); - processCodePoint((codePoint & 0x7F) + 0x40); + // processCodePoint(/* escape (hexadecimal=0x1B, octal=033): */27); + // 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 { switch (Character.getType(codePoint)) { case Character.UNASSIGNED: diff --git a/app/src/main/java/io/neoterm/ui/NeoTermActivity.kt b/app/src/main/java/io/neoterm/ui/NeoTermActivity.kt index d79dd15..3d696f8 100644 --- a/app/src/main/java/io/neoterm/ui/NeoTermActivity.kt +++ b/app/src/main/java/io/neoterm/ui/NeoTermActivity.kt @@ -114,7 +114,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference TabSwitcher.setupWithMenu(tabSwitcher, toolbar.menu, View.OnClickListener { val imm = this@NeoTermActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager if (!tabSwitcher.isSwitcherShown) { - if (imm.isActive) { + if (imm.isActive && tabSwitcher.selectedTab is TermTab) { val tab = tabSwitcher.selectedTab as TermTab tab.hideIme() } diff --git a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt index 924c090..b85fc84 100644 --- a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt +++ b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt @@ -68,10 +68,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen .setTitle(model.packageInfo.packageName) .setMessage(model.getPackageDetails(this@PackageManagerActivity)) .setPositiveButton(R.string.install, { _, _ -> - TerminalDialog(this@PackageManagerActivity) - .execute(NeoTermPath.APT_BIN_PATH, - arrayOf("apt", "install", "-y", model.packageInfo.packageName!!)) - .show("Installing ${model.packageInfo.packageName}") + installPackage(model.packageInfo.packageName) }) .setNegativeButton(android.R.string.no, null) .show() @@ -89,6 +86,20 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen 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 { menuInflater.inflate(R.menu.menu_pm, menu) val searchItem = menu!!.findItem(R.id.action_search) @@ -170,6 +181,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen TerminalDialog(this@PackageManagerActivity) .onFinish(object : TerminalDialog.SessionFinishedCallback { override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) { + dialog.dismiss() refreshPackageList() } }) diff --git a/app/src/main/java/io/neoterm/ui/settings/UISettingsActivity.kt b/app/src/main/java/io/neoterm/ui/settings/UISettingsActivity.kt index 0778722..dcbcfd1 100644 --- a/app/src/main/java/io/neoterm/ui/settings/UISettingsActivity.kt +++ b/app/src/main/java/io/neoterm/ui/settings/UISettingsActivity.kt @@ -4,6 +4,7 @@ import android.app.AlertDialog import android.os.Bundle import android.support.v7.app.AppCompatPreferenceActivity import android.view.MenuItem +import android.widget.Toast import io.neoterm.R import io.neoterm.backend.TerminalSession import io.neoterm.preference.NeoPreference @@ -39,9 +40,11 @@ class UISettingsActivity : AppCompatPreferenceActivity() { TerminalDialog(this) .onFinish(object : TerminalDialog.SessionFinishedCallback { override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) { - dialog.dismiss() if (finishedSession?.exitStatus == 0) { + dialog.dismiss() NeoPreference.store(R.string.key_general_shell, "zsh") + } else { + dialog.setTitle(getString(R.string.error)) } } }) diff --git a/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt b/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt index 60940fb..899a395 100644 --- a/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt +++ b/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt @@ -1,7 +1,6 @@ package io.neoterm.ui.setup import android.app.Activity -import android.content.DialogInterface import android.os.Bundle import android.support.v4.content.ContextCompat import android.support.v7.app.AlertDialog @@ -63,11 +62,17 @@ class SetupActivity : AppCompatActivity() { } TerminalDialog(this@SetupActivity) - .onDismiss(DialogInterface.OnCancelListener { - if (withShell != null) { - NeoPreference.store(R.string.key_general_shell, withShell!!) + .onFinish(object : TerminalDialog.SessionFinishedCallback { + override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) { + 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()) .show(getString(R.string.installer_message)) @@ -106,11 +111,13 @@ class SetupActivity : AppCompatActivity() { TerminalDialog(this) .onFinish(object : TerminalDialog.SessionFinishedCallback { override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) { - dialog.dismiss() nextButton.visibility = View.VISIBLE val exit = finishedSession?.exitStatus ?: 1 if (exit == 0) { + dialog.dismiss() aptUpdated = true + } else { + dialog.setTitle(getString(R.string.error)) } } }) diff --git a/app/src/main/java/io/neoterm/view/TerminalDialog.kt b/app/src/main/java/io/neoterm/view/TerminalDialog.kt index 6977e78..d8f1065 100644 --- a/app/src/main/java/io/neoterm/view/TerminalDialog.kt +++ b/app/src/main/java/io/neoterm/view/TerminalDialog.kt @@ -66,6 +66,11 @@ class TerminalDialog(val context: Context) { return this } + fun setTitle(title: String?) : TerminalDialog { + dialog?.setTitle(title) + return this + } + fun onFinish(finishedCallback: SessionFinishedCallback):TerminalDialog { this.sessionFinishedCallback = finishedCallback return this diff --git a/app/src/main/java/io/neoterm/view/TerminalView.java b/app/src/main/java/io/neoterm/view/TerminalView.java index c266253..95a7f6c 100755 --- a/app/src/main/java/io/neoterm/view/TerminalView.java +++ b/app/src/main/java/io/neoterm/view/TerminalView.java @@ -36,22 +36,32 @@ import io.neoterm.backend.TerminalBuffer; import io.neoterm.backend.TerminalEmulator; 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 { - /** Log view key and IME events. */ + /** + * Log view key and IME events. + */ 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; - /** Our terminal emulator whose session is {@link #mTermSession}. */ + /** + * Our terminal emulator whose session is {@link #mTermSession}. + */ TerminalEmulator mEmulator; TerminalRenderer mRenderer; 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; boolean mIsSelectingText = false, mIsDraggingLeftSelection, mInitialTextSelection; @@ -63,17 +73,25 @@ public final class TerminalView extends View { float mScaleFactor = 1.f; /* 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; - /** 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; /* final */ Scroller mScroller; - /** What was left in from scrolling movement. */ + /** + * What was left in from scrolling movement. + */ 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 mTextSize; @@ -429,7 +447,9 @@ public final class TerminalView extends View { 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) { int x = (int) (e.getX() / mRenderer.mFontWidth) + 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); } - /** 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) { boolean up = rowsDown < 0; 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 public boolean onGenericMotionEvent(MotionEvent event) { 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) { if (LOG_KEY_EVENTS) { Log.i(EmulatorDebug.LOG_TAG, "inputCodePoint(codePoint=" + codePoint + ", controlDownFromEvent=" + controlDownFromEvent + ", leftAltDownFromEvent=" - + leftAltDownFromEvent + ")"); + + leftAltDownFromEvent + ")"); } 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) { TerminalEmulator term = mTermSession.getEmulator(); String code = KeyHandler.getCode(keyCode, keyMod, term.isCursorKeysApplicationMode(), term.isKeypadApplicationMode()); @@ -751,7 +777,9 @@ public final class TerminalView extends View { 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() { int viewWidth = getWidth(); 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) public void toggleSelectingText(MotionEvent ev) { mIsSelectingText = !mIsSelectingText; @@ -851,6 +881,11 @@ public final class TerminalView extends View { @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + if (!mIsSelectingText) { + // Fix issue where the dialog is pressed while being dismissed. + return true; + } + switch (item.getItemId()) { case 1: String selectedText = mEmulator.getSelectedText(mSelX1, mSelY1, mSelX2, mSelY2).trim(); diff --git a/app/src/main/res/xml/backup_config.xml b/app/src/main/res/xml/backup_config.xml new file mode 100644 index 0000000..400d2ee --- /dev/null +++ b/app/src/main/res/xml/backup_config.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file