TerminalView: Use word based ime
This commit is contained in:
parent
9963c649b8
commit
aa7d28ba95
@ -46,8 +46,8 @@ class CandidatePopupWindow(val context: Context) {
|
||||
}
|
||||
|
||||
popWindow.showAtLocation(terminalView, Gravity.BOTTOM.and(Gravity.START),
|
||||
terminalView.cursorAbsX,
|
||||
terminalView.cursorAbsY)
|
||||
terminalView.cursorAbsoluteX,
|
||||
terminalView.cursorAbsoluteY)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ object DefaultValues {
|
||||
const val enableExplicitExtraKeysWeight = false
|
||||
const val enableBackButtonBeMappedToEscape = false
|
||||
const val enableSpecialVolumeKeys = false
|
||||
const val enableWordBasedIme = false
|
||||
|
||||
const val loginShell = "sh"
|
||||
const val initialCommand = ""
|
||||
|
@ -25,15 +25,8 @@ object NeoPreference {
|
||||
const val KEY_CURRENT_SESSION = "neoterm_service_current_session"
|
||||
const val KEY_SYSTEM_SHELL = "neoterm_core_system_shell"
|
||||
const val KEY_SOURCES = "neoterm_source_source_list"
|
||||
// const val KEY_FLOATING_WINDOW_X = "neoterm_floating_window_x"
|
||||
// const val KEY_FLOATING_WINDOW_Y = "neoterm_floating_window_y"
|
||||
// const val KEY_FLOATING_WIDTH = "neoterm_floating_window_width"
|
||||
// const val KEY_FLOATING_HEIGHT = "neoterm_floating_window_height"
|
||||
|
||||
const val VALUE_HAPPY_EGG_TRIGGER = 8
|
||||
const val VALUE_NEOTERM_ONLY = "NeoTermOnly"
|
||||
const val VALUE_NEOTERM_FIRST = "NeoTermFirst"
|
||||
const val VALUE_SYSTEM_FIRST = "SystemFirst"
|
||||
|
||||
var MIN_FONT_SIZE: Int = 0
|
||||
private set
|
||||
@ -243,22 +236,10 @@ object NeoPreference {
|
||||
DefaultValues.enableSwitchNextTab)
|
||||
}
|
||||
|
||||
// fun storeWindowSize(context: Context, width: Int, height: Int) {
|
||||
// store(KEY_FLOATING_WIDTH, width)
|
||||
// store(KEY_FLOATING_HEIGHT, height)
|
||||
// }
|
||||
//
|
||||
// fun storeWindowLocation(context: Context, x: Int, y: Int) {
|
||||
// store(KEY_FLOATING_WINDOW_X, x)
|
||||
// store(KEY_FLOATING_WINDOW_Y, y)Se
|
||||
// }
|
||||
//
|
||||
// fun applySavedWindowParameter(context: Context, layout: WindowManager.LayoutParams) {
|
||||
// layout.x = loadInt(KEY_FLOATING_WINDOW_X, 200)
|
||||
// layout.y = loadInt(KEY_FLOATING_WINDOW_Y, 200)
|
||||
// layout.width = loadInt(KEY_FLOATING_WIDTH, 500)
|
||||
// layout.height = loadInt(KEY_FLOATING_HEIGHT, 800)
|
||||
// }
|
||||
fun isWordBasedImeEnabled() : Boolean {
|
||||
return loadBoolean(R.string.key_general_enable_word_based_ime,
|
||||
DefaultValues.enableWordBasedIme)
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
|
@ -26,6 +26,7 @@ class ShellProfile : NeoProfile() {
|
||||
private const val EXTRA_KEYS = "extra-keys"
|
||||
private const val FONT = "font"
|
||||
private const val COLOR_SCHEME = "color-scheme"
|
||||
private const val WORD_BASED_IME = "word-based-ime"
|
||||
|
||||
private val PROFILE_META_PATH = arrayOf(PROFILE_META_NAME)
|
||||
}
|
||||
@ -42,6 +43,7 @@ class ShellProfile : NeoProfile() {
|
||||
var enableAutoCompletion = DefaultValues.enableAutoCompletion
|
||||
var enableBackKeyToEscape = DefaultValues.enableBackButtonBeMappedToEscape
|
||||
var enableExtraKeys = DefaultValues.enableExtraKeys
|
||||
var enableWordBasedIme = DefaultValues.enableWordBasedIme
|
||||
|
||||
var profileFont: String
|
||||
var profileColorScheme: String
|
||||
@ -62,6 +64,7 @@ class ShellProfile : NeoProfile() {
|
||||
enableAutoCompletion = NeoPreference.isAutoCompletionEnabled()
|
||||
enableBackKeyToEscape = NeoPreference.isBackButtonBeMappedToEscapeEnabled()
|
||||
enableExtraKeys = NeoPreference.isExtraKeysEnabled()
|
||||
enableWordBasedIme = NeoPreference.isWordBasedImeEnabled()
|
||||
}
|
||||
|
||||
override fun onProfileLoaded(visitor: ConfigVisitor): Boolean {
|
||||
@ -74,6 +77,7 @@ class ShellProfile : NeoProfile() {
|
||||
enableAutoCompletion = visitor.getProfileBoolean(AUTO_COMPLETION, enableAutoCompletion)
|
||||
enableBackKeyToEscape = visitor.getProfileBoolean(BACK_KEY_TO_ESC, enableBackKeyToEscape)
|
||||
enableExtraKeys = visitor.getProfileBoolean(EXTRA_KEYS, enableExtraKeys)
|
||||
enableWordBasedIme = visitor.getProfileBoolean(WORD_BASED_IME, enableWordBasedIme)
|
||||
profileFont = visitor.getProfileString(FONT, profileFont)
|
||||
profileColorScheme = visitor.getProfileString(COLOR_SCHEME, profileColorScheme)
|
||||
return true
|
||||
|
@ -14,7 +14,7 @@ import java.io.File
|
||||
open class ShellTermSession private constructor(shellPath: String, cwd: String,
|
||||
args: Array<String>, env: Array<String>,
|
||||
changeCallback: SessionChangedCallback,
|
||||
val initialCommand: String?,
|
||||
private val initialCommand: String?,
|
||||
val shellProfile: ShellProfile)
|
||||
: TerminalSession(shellPath, cwd, args, env, changeCallback) {
|
||||
|
||||
|
@ -10,26 +10,26 @@ import io.neoterm.frontend.session.shell.ShellTermSession
|
||||
* @author kiva
|
||||
*/
|
||||
class TermSessionCallback : TerminalSession.SessionChangedCallback {
|
||||
var termData: TermDataHolder? = null
|
||||
var termSessionData: TermSessionData? = null
|
||||
|
||||
var bellController: BellController? = null
|
||||
|
||||
override fun onTextChanged(changedSession: TerminalSession?) {
|
||||
termData?.termView?.onScreenUpdated()
|
||||
termSessionData?.termView?.onScreenUpdated()
|
||||
}
|
||||
|
||||
override fun onTitleChanged(changedSession: TerminalSession?) {
|
||||
if (changedSession?.title != null) {
|
||||
termData?.termUI?.requireUpdateTitle(changedSession.title)
|
||||
termSessionData?.termUI?.requireUpdateTitle(changedSession.title)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSessionFinished(finishedSession: TerminalSession?) {
|
||||
termData?.termUI?.requireOnSessionFinished()
|
||||
termSessionData?.termUI?.requireOnSessionFinished()
|
||||
}
|
||||
|
||||
override fun onClipboardText(session: TerminalSession?, text: String?) {
|
||||
val termView = termData?.termView
|
||||
val termView = termSessionData?.termView
|
||||
if (termView != null) {
|
||||
val clipboard = termView.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
clipboard.primaryClip = ClipData.newPlainText("", text)
|
||||
@ -37,7 +37,7 @@ class TermSessionCallback : TerminalSession.SessionChangedCallback {
|
||||
}
|
||||
|
||||
override fun onBell(session: TerminalSession?) {
|
||||
val termView = termData?.termView ?: return
|
||||
val termView = termSessionData?.termView ?: return
|
||||
val shellSession = session as ShellTermSession
|
||||
|
||||
if (bellController == null) {
|
||||
@ -48,7 +48,7 @@ class TermSessionCallback : TerminalSession.SessionChangedCallback {
|
||||
}
|
||||
|
||||
override fun onColorsChanged(session: TerminalSession?) {
|
||||
val termView = termData?.termView
|
||||
val termView = termSessionData?.termView
|
||||
if (session != null && termView != null) {
|
||||
termView.onScreenUpdated()
|
||||
}
|
||||
|
@ -2,13 +2,15 @@ package io.neoterm.frontend.session.shell.client
|
||||
|
||||
import io.neoterm.backend.TerminalSession
|
||||
import io.neoterm.frontend.completion.listener.OnAutoCompleteListener
|
||||
import io.neoterm.frontend.session.shell.ShellProfile
|
||||
import io.neoterm.frontend.session.shell.ShellTermSession
|
||||
import io.neoterm.frontend.terminal.TerminalView
|
||||
import io.neoterm.frontend.terminal.extrakey.ExtraKeysView
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class TermDataHolder {
|
||||
class TermSessionData {
|
||||
var termSession: TerminalSession? = null
|
||||
var sessionCallback: TermSessionCallback? = null
|
||||
var viewClient: TermViewClient? = null
|
||||
@ -18,25 +20,33 @@ class TermDataHolder {
|
||||
var termView: TerminalView? = null
|
||||
var extraKeysView: ExtraKeysView? = null
|
||||
|
||||
var profile: ShellProfile? = null
|
||||
|
||||
fun cleanup() {
|
||||
onAutoCompleteListener?.onCleanUp()
|
||||
onAutoCompleteListener = null
|
||||
|
||||
sessionCallback?.termData = null
|
||||
viewClient?.termData = null
|
||||
sessionCallback?.termSessionData = null
|
||||
viewClient?.termSessionData = null
|
||||
|
||||
termUI = null
|
||||
termView = null
|
||||
extraKeysView = null
|
||||
termSession = null
|
||||
|
||||
profile = null
|
||||
}
|
||||
|
||||
fun initializeSessionWith(session: TerminalSession, sessionCallback: TermSessionCallback?, viewClient: TermViewClient?) {
|
||||
this.termSession = session
|
||||
this.sessionCallback = sessionCallback
|
||||
this.viewClient = viewClient
|
||||
this.sessionCallback?.termData = this
|
||||
this.viewClient?.termData = this
|
||||
this.sessionCallback?.termSessionData = this
|
||||
this.viewClient?.termSessionData = this
|
||||
|
||||
if (session is ShellTermSession) {
|
||||
profile = session.shellProfile
|
||||
}
|
||||
}
|
||||
|
||||
fun initializeViewWith(termUI: TermUiPresenter?, termView: TerminalView?, eks: ExtraKeysView?) {
|
@ -24,7 +24,7 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
private var mVirtualFnKeyDown: Boolean = false
|
||||
private var lastTitle: String = ""
|
||||
|
||||
var termData: TermDataHolder? = null
|
||||
var termSessionData: TermSessionData? = null
|
||||
|
||||
override fun onScale(scale: Float): Float {
|
||||
if (scale < 0.9f || scale > 1.1f) {
|
||||
@ -36,13 +36,13 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
}
|
||||
|
||||
override fun onSingleTapUp(e: MotionEvent?) {
|
||||
val termView = termData?.termView ?: return
|
||||
val termView = termSessionData?.termView ?: return
|
||||
(context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager)
|
||||
.showSoftInput(termView, InputMethodManager.SHOW_IMPLICIT)
|
||||
}
|
||||
|
||||
override fun shouldBackButtonBeMappedToEscape(): Boolean {
|
||||
val shellSession = termData?.termSession as ShellTermSession? ?: return false
|
||||
val shellSession = termSessionData?.termSession as ShellTermSession? ?: return false
|
||||
return shellSession.shellProfile.enableBackKeyToEscape
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
return true
|
||||
}
|
||||
|
||||
val termUI = termData?.termUI
|
||||
val termUI = termSessionData?.termUI
|
||||
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_ENTER -> {
|
||||
@ -112,12 +112,12 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
}
|
||||
|
||||
override fun readControlKey(): Boolean {
|
||||
val extraKeysView = termData?.extraKeysView
|
||||
val extraKeysView = termSessionData?.extraKeysView
|
||||
return (extraKeysView != null && extraKeysView.readControlButton()) || mVirtualControlKeyDown
|
||||
}
|
||||
|
||||
override fun readAltKey(): Boolean {
|
||||
val extraKeysView = termData?.extraKeysView
|
||||
val extraKeysView = termSessionData?.extraKeysView
|
||||
return (extraKeysView != null && extraKeysView.readAltButton()) || mVirtualFnKeyDown
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
return false
|
||||
}
|
||||
|
||||
val shellSession = termData?.termSession as ShellTermSession? ?: return false
|
||||
val shellSession = termSessionData?.termSession as ShellTermSession? ?: return false
|
||||
|
||||
// Volume keys as special keys
|
||||
val volumeAsSpecialKeys = shellSession.shellProfile.enableSpecialVolumeKeys
|
||||
@ -213,7 +213,7 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
}
|
||||
|
||||
fun updateExtraKeys(title: String?, force: Boolean = false) {
|
||||
val extraKeysView = termData?.extraKeysView
|
||||
val extraKeysView = termSessionData?.extraKeysView
|
||||
|
||||
if (extraKeysView == null || title == null || title.isEmpty()) {
|
||||
return
|
||||
@ -229,8 +229,8 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
}
|
||||
|
||||
private fun updateExtraKeysVisibility(): Boolean {
|
||||
val extraKeysView = termData?.extraKeysView ?: return false
|
||||
val shellSession = termData?.termSession as ShellTermSession? ?: return false
|
||||
val extraKeysView = termSessionData?.extraKeysView ?: return false
|
||||
val shellSession = termSessionData?.termSession as ShellTermSession? ?: return false
|
||||
|
||||
return if (shellSession.shellProfile.enableExtraKeys) {
|
||||
extraKeysView.visibility = View.VISIBLE
|
||||
@ -242,12 +242,12 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
}
|
||||
|
||||
private fun removeExtraKeys() {
|
||||
val extraKeysView = termData?.extraKeysView
|
||||
val extraKeysView = termSessionData?.extraKeysView
|
||||
extraKeysView?.clearUserKeys()
|
||||
}
|
||||
|
||||
private fun changeFontSize(increase: Boolean) {
|
||||
val termView = termData?.termView
|
||||
val termView = termSessionData?.termView
|
||||
if (termView != null) {
|
||||
val changedSize = (if (increase) 1 else -1) * 2
|
||||
val fontSize = NeoPreference.validateFontSize(termView.textSize + changedSize)
|
||||
|
@ -97,6 +97,11 @@ public final class TerminalView extends View {
|
||||
int mCombiningAccent;
|
||||
int mTextSize;
|
||||
|
||||
/**
|
||||
* If true, IME will be word based instead of char based.
|
||||
*/
|
||||
private boolean mEnableWordBasedIme = false;
|
||||
|
||||
public TerminalView(Context context) {
|
||||
super(context);
|
||||
commonInit(context);
|
||||
@ -325,7 +330,12 @@ public final class TerminalView extends View {
|
||||
// https://github.com/termux/termux-app/issues/87.
|
||||
// https://github.com/termux/termux-app/issues/126.
|
||||
// https://github.com/termux/termux-app/issues/137 (japanese chars and TYPE_NULL).
|
||||
outAttrs.inputType = InputType.TYPE_NULL;
|
||||
if (mEnableWordBasedIme) {
|
||||
// Workaround for Google Pinying cannot input Chinese
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
|
||||
} else {
|
||||
outAttrs.inputType = InputType.TYPE_NULL;
|
||||
}
|
||||
|
||||
// Note that IME_ACTION_NONE cannot be used as that makes it impossible to input newlines using the on-screen
|
||||
// keyboard on Android TV (see https://github.com/termux/termux-app/issues/221).
|
||||
@ -1089,13 +1099,17 @@ public final class TerminalView extends View {
|
||||
this.onAutoCompleteListener = onAutoCompleteListener;
|
||||
}
|
||||
|
||||
public int getCursorAbsX() {
|
||||
public int getCursorAbsoluteX() {
|
||||
return (int) mRenderer.getCursorX();
|
||||
}
|
||||
|
||||
public int getCursorAbsY() {
|
||||
public int getCursorAbsoluteY() {
|
||||
int[] locations = new int[2];
|
||||
getLocationOnScreen(locations);
|
||||
return (int) (mRenderer.getCursorY() + locations[1]);
|
||||
}
|
||||
|
||||
public void setEnableWordBasedIme(boolean mEnableWordBasedIme) {
|
||||
this.mEnableWordBasedIme = mEnableWordBasedIme;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import io.neoterm.NeoGLView
|
||||
import io.neoterm.R
|
||||
import io.neoterm.component.color.ColorSchemeComponent
|
||||
import io.neoterm.frontend.component.ComponentManager
|
||||
import io.neoterm.frontend.config.DefaultValues
|
||||
import io.neoterm.frontend.terminal.TerminalView
|
||||
import io.neoterm.frontend.terminal.extrakey.ExtraKeysView
|
||||
import io.neoterm.ui.term.NeoTermActivity
|
||||
@ -26,8 +27,9 @@ import io.neoterm.utils.TerminalUtils
|
||||
*/
|
||||
class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
|
||||
companion object {
|
||||
private val VIEW_TYPE_TERM = 1
|
||||
private val VIEW_TYPE_X = 2
|
||||
private var VIEW_TYPE_COUNT = 0
|
||||
private val VIEW_TYPE_TERM = VIEW_TYPE_COUNT++
|
||||
private val VIEW_TYPE_X = VIEW_TYPE_COUNT++
|
||||
}
|
||||
|
||||
private fun setViewLayerType(view: View?) = view?.setLayerType(View.LAYER_TYPE_NONE, null)
|
||||
@ -146,6 +148,7 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
|
||||
val termData = tab.termData
|
||||
|
||||
termData.initializeViewWith(tab, termView, extraKeysView)
|
||||
termView.setEnableWordBasedIme(termData.profile?.enableWordBasedIme ?: DefaultValues.enableWordBasedIme)
|
||||
termView.setTerminalViewClient(termData.viewClient)
|
||||
termView.attachSession(termData.termSession)
|
||||
|
||||
@ -155,7 +158,7 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
|
||||
}
|
||||
|
||||
override fun getViewTypeCount(): Int {
|
||||
return 2
|
||||
return VIEW_TYPE_COUNT
|
||||
}
|
||||
|
||||
override fun getViewType(tab: Tab, index: Int): Int {
|
||||
@ -164,6 +167,6 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
|
||||
} else if (tab is XSessionTab) {
|
||||
return VIEW_TYPE_X
|
||||
}
|
||||
return 0
|
||||
return -1
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import android.content.Context
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import io.neoterm.component.color.ColorSchemeComponent
|
||||
import io.neoterm.frontend.session.shell.client.TermDataHolder
|
||||
import io.neoterm.frontend.session.shell.client.TermSessionData
|
||||
import io.neoterm.frontend.session.shell.client.TermUiPresenter
|
||||
import io.neoterm.frontend.session.shell.client.event.*
|
||||
import io.neoterm.frontend.component.ComponentManager
|
||||
@ -19,7 +19,7 @@ class TermTab(title: CharSequence) : NeoTab(title), TermUiPresenter {
|
||||
val PARAMETER_SHOW_EKS = "show_eks"
|
||||
}
|
||||
|
||||
var termData = TermDataHolder()
|
||||
var termData = TermSessionData()
|
||||
var toolbar: Toolbar? = null
|
||||
|
||||
fun updateColorScheme() {
|
||||
|
@ -22,6 +22,8 @@
|
||||
<string name="pref_general_volume_as_control_desc">音量下为 Ctrl\n音量上为 FN</string>
|
||||
<string name="pref_general_use_execve_wrapper">使用自定义的 execve()</string>
|
||||
<string name="pref_general_use_execve_wrapper_desc">接管 execve() 来兼容 linux 风格的 shebang</string>
|
||||
<string name="pref_general_enable_word_based_ime">启用基于单词的输入法</string>
|
||||
<string name="pref_general_enable_word_based_ime_desc">输入单位为单词而不是字母(谷歌输入法无法输入中文可以勾选此选项)</string>
|
||||
<string name="pref_package_source">软件源</string>
|
||||
<string name="pref_ui_close_tab_anim_next_tab">向下切换窗口</string>
|
||||
<string name="pref_ui_close_tab_anim_next_tab_desc">关闭当前窗口时切换到下一个窗口而不是上一个</string>
|
||||
|
@ -8,6 +8,7 @@
|
||||
<string name="key_general_auto_completion" translatable="false">neoterm_general_auto_completion</string>
|
||||
<string name="key_general_volume_as_control" translatable="false">neoterm_general_volume_as_control</string>
|
||||
<string name="key_general_use_execve_wrapper" translatable="false">neoterm_general_use_execve_wrapper</string>
|
||||
<string name="key_general_enable_word_based_ime" translatable="false">neoterm_general_enable_word_based_ime</string>
|
||||
|
||||
<string name="key_ui_fullscreen" translatable="false">neoterm_ui_fullscreen</string>
|
||||
<string name="key_ui_hide_toolbar" translatable="false">neoterm_ui_hide_toolbar</string>
|
||||
|
@ -89,6 +89,8 @@
|
||||
<string name="pref_general_volume_as_control_desc">Volume Down as Ctrl\nVolume Up as FN</string>
|
||||
<string name="pref_general_use_execve_wrapper">Use execve() wrapper</string>
|
||||
<string name="pref_general_use_execve_wrapper_desc">Hook execve() to avoid incorrect shebang</string>
|
||||
<string name="pref_general_enable_word_based_ime">Enable word based IME</string>
|
||||
<string name="pref_general_enable_word_based_ime_desc">Word based or char based IME</string>
|
||||
<string name="pref_ui_fullscreen">Full Screen</string>
|
||||
<string name="pref_ui_hide_toolbar">Hide Toolbar</string>
|
||||
<string name="pref_ui_hide_toolbar_desc">Hide toolbar when keyboard is showing</string>
|
||||
|
@ -43,6 +43,12 @@
|
||||
android:summary="@string/pref_general_use_execve_wrapper_desc"
|
||||
android:title="@string/pref_general_use_execve_wrapper" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_general_enable_word_based_ime"
|
||||
android:summary="@string/pref_general_enable_word_based_ime_desc"
|
||||
android:title="@string/pref_general_enable_word_based_ime" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_general_auto_completion"
|
||||
|
Loading…
Reference in New Issue
Block a user