Fix: Hide terminal toolbar if tab switcher is showing

Fix: Unable to click the firse tab after closing other tabs
This commit is contained in:
zt515
2017-06-12 14:35:26 +08:00
parent a6bf16bc83
commit ce5b7ededb
11 changed files with 93 additions and 57 deletions

View File

@ -11,6 +11,7 @@ import android.support.v4.view.OnApplyWindowInsetsListener
import android.support.v4.view.ViewCompat import android.support.v4.view.ViewCompat
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar import android.support.v7.widget.Toolbar
import android.util.Log
import android.view.View import android.view.View
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.ImageButton import android.widget.ImageButton
@ -61,7 +62,25 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
.setToolbarNavigationIcon(R.drawable.ic_add_box_white_24dp, createAddSessionListener()) .setToolbarNavigationIcon(R.drawable.ic_add_box_white_24dp, createAddSessionListener())
tabSwitcher.inflateToolbarMenu(R.menu.tab_switcher, createToolbarMenuListener()) tabSwitcher.inflateToolbarMenu(R.menu.tab_switcher, createToolbarMenuListener())
tabSwitcher.addListener(object : TabSwitcherListener { tabSwitcher.addListener(object : TabSwitcherListener {
private var tabSwitcherButtonInited = false
override fun onSwitcherShown(tabSwitcher: TabSwitcher) { override fun onSwitcherShown(tabSwitcher: TabSwitcher) {
if (tabSwitcherButtonInited) {
return
}
val menu = tabSwitcher.toolbarMenu
if (menu != null) {
tabSwitcherButtonInited = true
val tabSwitcherButton = menu.findItem(R.id.toggle_tab_switcher_menu_item).actionView as TabSwitcherButton
tabSwitcherButton.setOnClickListener {
if (tabSwitcher.isSwitcherShown) {
tabSwitcher.hideSwitcher()
} else {
tabSwitcher.showSwitcher()
}
}
}
} }
override fun onSwitcherHidden(tabSwitcher: TabSwitcher) { override fun onSwitcherHidden(tabSwitcher: TabSwitcher) {
@ -79,13 +98,8 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
override fun onTabRemoved(tabSwitcher: TabSwitcher, index: Int, tab: Tab, animation: Animation) { override fun onTabRemoved(tabSwitcher: TabSwitcher, index: Int, tab: Tab, animation: Animation) {
if (tab is TermTab) { if (tab is TermTab) {
tab.termSession?.finishIfRunning()
tab.viewClient?.termView = null
tab.viewClient?.extraKeysView = null
tab.sessionCallback?.termView = null
removeFinishedSession(tab.termSession) removeFinishedSession(tab.termSession)
tab.termSession = null tab.cleanup()
} }
updateTabSwitcherButton() updateTabSwitcherButton()
} }
@ -180,7 +194,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
} }
private fun getStoredCurrentSessionOrLast(): TerminalSession? { private fun getStoredCurrentSessionOrLast(): TerminalSession? {
val stored = NeoTermPreference.getCurrentSession(this) val stored = NeoTermPreference.getCurrentSession(termService)
if (stored != null) return stored if (stored != null) return stored
val numberOfSessions = termService!!.sessions.size val numberOfSessions = termService!!.sessions.size
if (numberOfSessions == 0) return null if (numberOfSessions == 0) return null

View File

@ -15,7 +15,6 @@ import android.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import io.neoterm.tab.TermSessionChangedCallback;
import io.neoterm.terminal.EmulatorDebug; import io.neoterm.terminal.EmulatorDebug;
import io.neoterm.terminal.TerminalSession; import io.neoterm.terminal.TerminalSession;
@ -79,7 +78,7 @@ public class NeoTermService extends Service {
return mTerminalSessions; return mTerminalSessions;
} }
TerminalSession createTermSession(String executablePath, String[] arguments, String cwd, String[] env, TermSessionChangedCallback sessionCallback) { TerminalSession createTermSession(String executablePath, String[] arguments, String cwd, String[] env, TerminalSession.SessionChangedCallback sessionCallback) {
if (cwd == null) cwd = getFilesDir().getAbsolutePath(); if (cwd == null) cwd = getFilesDir().getAbsolutePath();
boolean isLoginShell = false; boolean isLoginShell = false;

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.preference.PreferenceManager import android.preference.PreferenceManager
import io.neoterm.NeoTermActivity import io.neoterm.NeoTermActivity
import io.neoterm.NeoTermService
import io.neoterm.terminal.TerminalSession import io.neoterm.terminal.TerminalSession
/** /**
@ -17,12 +18,12 @@ object NeoTermPreference {
PreferenceManager.getDefaultSharedPreferences(context).edit().putString(NeoTermPreference.CURRENT_SESSION_KEY, session.mHandle).apply() PreferenceManager.getDefaultSharedPreferences(context).edit().putString(NeoTermPreference.CURRENT_SESSION_KEY, session.mHandle).apply()
} }
fun getCurrentSession(termActivity: NeoTermActivity): TerminalSession? { fun getCurrentSession(termService: NeoTermService?): TerminalSession? {
val sessionHandle = PreferenceManager.getDefaultSharedPreferences(termActivity).getString(CURRENT_SESSION_KEY, "") val sessionHandle = PreferenceManager.getDefaultSharedPreferences(termService!!).getString(CURRENT_SESSION_KEY, "")
var i = 0 var i = 0
val len = termActivity.termService!!.sessions.size val len = termService.sessions.size
while (i < len) { while (i < len) {
val session = termActivity.termService!!.sessions[i] val session = termService.sessions[i]
if (session.mHandle == sessionHandle) return session if (session.mHandle == sessionHandle) return session
i++ i++
} }

View File

@ -8,13 +8,16 @@ import io.neoterm.view.TerminalView
*/ */
class TermSessionChangedCallback : TerminalSession.SessionChangedCallback { class TermSessionChangedCallback : TerminalSession.SessionChangedCallback {
var termView: TerminalView? = null var termView: TerminalView? = null
var termTab: TermTab? = null
override fun onTextChanged(changedSession: TerminalSession?) { override fun onTextChanged(changedSession: TerminalSession?) {
termView?.onScreenUpdated() termView?.onScreenUpdated()
} }
override fun onTitleChanged(changedSession: TerminalSession?) { override fun onTitleChanged(changedSession: TerminalSession?) {
if (changedSession?.title != null) {
termTab?.updateTitle(changedSession.title)
}
} }
override fun onSessionFinished(finishedSession: TerminalSession?) { override fun onSessionFinished(finishedSession: TerminalSession?) {
@ -22,15 +25,11 @@ class TermSessionChangedCallback : TerminalSession.SessionChangedCallback {
} }
override fun onClipboardText(session: TerminalSession?, text: String?) { override fun onClipboardText(session: TerminalSession?, text: String?) {
} }
override fun onBell(session: TerminalSession?) { override fun onBell(session: TerminalSession?) {
} }
override fun onColorsChanged(session: TerminalSession?) { override fun onColorsChanged(session: TerminalSession?) {
} }
} }

View File

@ -2,6 +2,7 @@ package io.neoterm.tab
import android.os.Parcel import android.os.Parcel
import android.os.Parcelable import android.os.Parcelable
import android.support.v7.widget.Toolbar
import de.mrapp.android.tabswitcher.Tab import de.mrapp.android.tabswitcher.Tab
import io.neoterm.terminal.TerminalSession import io.neoterm.terminal.TerminalSession
@ -13,11 +14,22 @@ class TermTab : Tab {
var termSession: TerminalSession? = null var termSession: TerminalSession? = null
var sessionCallback: TermSessionChangedCallback? = null var sessionCallback: TermSessionChangedCallback? = null
var viewClient: TermViewClient? = null var viewClient: TermViewClient? = null
var toolbar: Toolbar? = null
constructor(title: CharSequence) : super(title) constructor(title: CharSequence) : super(title)
private constructor(source: Parcel) : super(source) private constructor(source: Parcel) : super(source)
fun cleanup() {
termSession?.finishIfRunning()
viewClient?.termView = null
viewClient?.extraKeysView = null
sessionCallback?.termView = null
sessionCallback?.termTab = null
toolbar = null
termSession = null
}
companion object { companion object {
val CREATOR: Parcelable.Creator<TermTab> = object : Parcelable.Creator<TermTab> { val CREATOR: Parcelable.Creator<TermTab> = object : Parcelable.Creator<TermTab> {
override fun createFromParcel(source: Parcel): TermTab { override fun createFromParcel(source: Parcel): TermTab {
@ -29,4 +41,9 @@ class TermTab : Tab {
} }
} }
} }
fun updateTitle(title: String) {
this.title = title
toolbar?.title = title
}
} }

View File

@ -1,7 +1,6 @@
package io.neoterm.tab package io.neoterm.tab
import android.content.Context import android.content.Context
import android.graphics.Color
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Bundle import android.os.Bundle
import android.support.v7.widget.Toolbar import android.support.v7.widget.Toolbar
@ -13,7 +12,6 @@ import de.mrapp.android.tabswitcher.TabSwitcher
import de.mrapp.android.tabswitcher.TabSwitcherDecorator import de.mrapp.android.tabswitcher.TabSwitcherDecorator
import io.neoterm.NeoTermActivity import io.neoterm.NeoTermActivity
import io.neoterm.R import io.neoterm.R
import io.neoterm.terminal.TerminalSession
import io.neoterm.view.ExtraKeysView import io.neoterm.view.ExtraKeysView
import io.neoterm.view.TerminalView import io.neoterm.view.TerminalView
@ -38,33 +36,45 @@ class TermTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
override fun onShowTab(context: Context, tabSwitcher: TabSwitcher, override fun onShowTab(context: Context, tabSwitcher: TabSwitcher,
view: View, tab: Tab, index: Int, viewType: Int, savedInstanceState: Bundle?) { view: View, tab: Tab, index: Int, viewType: Int, savedInstanceState: Bundle?) {
val toolbar = findViewById<Toolbar>(R.id.terminal_toolbar) val toolbar = findViewById<Toolbar>(R.id.terminal_toolbar)
toolbar?.title = tab.title toolbar.title = tab.title
if (tabSwitcher.isSwitcherShown) {
toolbar.visibility = View.GONE
} else {
toolbar.visibility = View.VISIBLE
}
if (tab is TermTab) {
tab.toolbar = toolbar
}
val terminalView = findViewById<TerminalView>(R.id.terminal_view) val terminalView = findViewById<TerminalView>(R.id.terminal_view)
val extraKeysView = findViewById<ExtraKeysView>(R.id.extra_keys) val extraKeysView = findViewById<ExtraKeysView>(R.id.extra_keys)
setupTerminalView(tab, terminalView, extraKeysView) bindTerminalView(tab, terminalView, extraKeysView)
terminalView.requestFocus() terminalView.requestFocus()
} }
private fun setupTerminalView(tab: Tab, view: TerminalView?, extraKeysView: ExtraKeysView?) { private fun bindTerminalView(tab: Tab, view: TerminalView?, extraKeysView: ExtraKeysView?) {
if (view == null) { if (view == null) {
return return
} }
view.setBackgroundColor(Color.BLACK)
view.textSize = 30 view.textSize = 30
view.setTypeface(Typeface.MONOSPACE) view.setTypeface(Typeface.MONOSPACE)
val termTab = tab as TermTab if (tab is TermTab) {
val termTab = tab
// 复用前一次的 TermSession // 复用前一次的 TermSession
termTab.sessionCallback?.termView = view termTab.sessionCallback?.termView = view
termTab.sessionCallback?.termTab = tab
// 复用上一次的 TermViewClient // 复用上一次的 TermViewClient
termTab.viewClient?.termView = view termTab.viewClient?.termView = view
termTab.viewClient?.extraKeysView = extraKeysView termTab.viewClient?.extraKeysView = extraKeysView
view.setOnKeyListener(termTab.viewClient) view.setOnKeyListener(termTab.viewClient)
view.attachSession(termTab.termSession) view.attachSession(termTab.termSession)
}
} }
override fun getViewTypeCount(): Int { override fun getViewTypeCount(): Int {

View File

@ -17,7 +17,7 @@
android:id="@+id/extra_keys" android:id="@+id/extra_keys"
style="?android:buttonBarStyle" style="?android:buttonBarStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="36dp"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:background="@color/terminal_background" android:background="@color/terminal_background"
android:orientation="horizontal" /> android:orientation="horizontal" />

View File

@ -7,7 +7,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha1' classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View File

@ -27,6 +27,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.StringRes; import android.support.annotation.StringRes;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils; import android.text.TextUtils;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;

View File

@ -191,7 +191,8 @@ public class PhoneDragHandler extends AbstractDragHandler<PhoneDragHandler.Callb
while ((tabItem = iterator.next()) != null) { while ((tabItem = iterator.next()) != null) {
if (tabItem.getTag().getState() == State.FLOATING || if (tabItem.getTag().getState() == State.FLOATING ||
tabItem.getTag().getState() == State.STACKED_START_ATOP) { tabItem.getTag().getState() == State.STACKED_START_ATOP ||
tabItem.getTag().getState() == State.STACKED_START) {
View view = tabItem.getView(); View view = tabItem.getView();
Toolbar[] toolbars = getTabSwitcher().getToolbars(); Toolbar[] toolbars = getTabSwitcher().getToolbars();
float toolbarHeight = getTabSwitcher().getLayout() != Layout.PHONE_LANDSCAPE && float toolbarHeight = getTabSwitcher().getLayout() != Layout.PHONE_LANDSCAPE &&

View File

@ -19,6 +19,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatImageButton; import android.support.v7.widget.AppCompatImageButton;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View;
import de.mrapp.android.tabswitcher.Animation; import de.mrapp.android.tabswitcher.Animation;
import de.mrapp.android.tabswitcher.R; import de.mrapp.android.tabswitcher.R;
@ -62,9 +63,8 @@ public class TabSwitcherButton extends AppCompatImageButton implements TabSwitch
* Creates a new image button, which allows to display the number of tabs, which are currently * Creates a new image button, which allows to display the number of tabs, which are currently
* contained by a {@link TabSwitcher}. * contained by a {@link TabSwitcher}.
* *
* @param context * @param context The context, which should be used by the view, as an instance of the class {@link
* The context, which should be used by the view, as an instance of the class {@link * Context}. The context may not be null
* Context}. The context may not be null
*/ */
public TabSwitcherButton(@NonNull final Context context) { public TabSwitcherButton(@NonNull final Context context) {
this(context, null); this(context, null);
@ -74,12 +74,10 @@ public class TabSwitcherButton extends AppCompatImageButton implements TabSwitch
* Creates a new image button, which allows to display the number of tabs, which are currently * Creates a new image button, which allows to display the number of tabs, which are currently
* contained by a {@link TabSwitcher}. * contained by a {@link TabSwitcher}.
* *
* @param context * @param context The context, which should be used by the view, as an instance of the class {@link
* The context, which should be used by the view, as an instance of the class {@link * Context}. The context may not be null
* Context}. The context may not be null * @param attributeSet The attribute set, the view's attributes should be obtained from, as an instance of
* @param attributeSet * the type {@link AttributeSet} or null, if no attributes should be obtained
* The attribute set, the view's attributes should be obtained from, as an instance of
* the type {@link AttributeSet} or null, if no attributes should be obtained
*/ */
public TabSwitcherButton(@NonNull final Context context, public TabSwitcherButton(@NonNull final Context context,
@Nullable final AttributeSet attributeSet) { @Nullable final AttributeSet attributeSet) {
@ -91,16 +89,13 @@ public class TabSwitcherButton extends AppCompatImageButton implements TabSwitch
* Creates a new image button, which allows to display the number of tabs, which are currently * Creates a new image button, which allows to display the number of tabs, which are currently
* contained by a {@link TabSwitcher}. * contained by a {@link TabSwitcher}.
* *
* @param context * @param context The context, which should be used by the view, as an instance of the class {@link
* The context, which should be used by the view, as an instance of the class {@link * Context}. The context may not be null
* Context}. The context may not be null * @param attributeSet The attribute set, the view's attributes should be obtained from, as an instance of
* @param attributeSet * the type {@link AttributeSet} or null, if no attributes should be obtained
* The attribute set, the view's attributes should be obtained from, as an instance of * @param defaultStyle The default style to apply to this view. If 0, no style will be applied (beyond what
* the type {@link AttributeSet} or null, if no attributes should be obtained * is included in the theme). This may either be an attribute resource, whose value will
* @param defaultStyle * be retrieved from the current theme, or an explicit style resource
* The default style to apply to this view. If 0, no style will be applied (beyond what
* is included in the theme). This may either be an attribute resource, whose value will
* be retrieved from the current theme, or an explicit style resource
*/ */
public TabSwitcherButton(@NonNull final Context context, public TabSwitcherButton(@NonNull final Context context,
@Nullable final AttributeSet attributeSet, @Nullable final AttributeSet attributeSet,
@ -112,9 +107,8 @@ public class TabSwitcherButton extends AppCompatImageButton implements TabSwitch
/** /**
* Updates the image button to display a specific value. * Updates the image button to display a specific value.
* *
* @param count * @param count The value, which should be displayed, as an {@link Integer} value. The value must be
* The value, which should be displayed, as an {@link Integer} value. The value must be * at least 0
* at least 0
*/ */
public final void setCount(final int count) { public final void setCount(final int count) {
drawable.setCount(count); drawable.setCount(count);