Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android N multi-window support #187

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@

<activity
android:name="com.termux.app.TermuxActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:launchMode="singleTask"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"
android:launchMode="standard"
android:windowSoftInputMode="adjustResize|stateAlwaysVisible" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
111 changes: 97 additions & 14 deletions app/src/main/java/com/termux/app/TermuxActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
Expand Down Expand Up @@ -115,6 +116,8 @@ public final class TermuxActivity extends Activity implements ServiceConnection

TermuxPreferences mSettings;

SessionChangedCallback mSessionChangedCallback;

/**
* The connection to the {@link TermuxService}. Requested in {@link #onCreate(Bundle)} with a call to
* {@link #bindService(Intent, ServiceConnection, int)}, and obtained and stored in
Expand Down Expand Up @@ -206,6 +209,7 @@ public boolean ensureStoragePermissionGranted() {
}

@Override
@TargetApi(Build.VERSION_CODES.N)
public void onCreate(Bundle bundle) {
super.onCreate(bundle);

Expand Down Expand Up @@ -307,6 +311,14 @@ public void onTextSet(String text) {
}
});

View newWindowButton = findViewById(R.id.new_window_button);
newWindowButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
addNewWindow();
}
});

findViewById(R.id.toggle_keyboard_button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Expand Down Expand Up @@ -335,6 +347,10 @@ public boolean onLongClick(View v) {
checkForFontAndColors();

mBellSoundId = mBellSoundPool.load(this, R.raw.bell, 1);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
onMultiWindowModeChanged(isInMultiWindowMode());
}
}

void toggleShowExtraKeys() {
Expand All @@ -356,7 +372,7 @@ void toggleShowExtraKeys() {
public void onServiceConnected(ComponentName componentName, IBinder service) {
mTermService = ((TermuxService.LocalBinder) service).service;

mTermService.mSessionChangeCallback = new SessionChangedCallback() {
mSessionChangedCallback = new SessionChangedCallback() {
@Override
public void onTextChanged(TerminalSession changedSession) {
if (!mIsVisible) return;
Expand All @@ -375,6 +391,12 @@ public void onTitleChanged(TerminalSession updatedSession) {
mListViewAdapter.notifyDataSetChanged();
}

@Override
public void onSessionCreated(TerminalSession createdSession) {
if (!mIsVisible) return;
mListViewAdapter.notifyDataSetChanged();
}

@Override
public void onSessionFinished(final TerminalSession finishedSession) {
if (mTermService.mWantsToStop) {
Expand All @@ -392,6 +414,18 @@ public void onSessionFinished(final TerminalSession finishedSession) {
mListViewAdapter.notifyDataSetChanged();
}

@Override
public void onSessionRemoved(TerminalSession removedSession) {
if (!mIsVisible) return;
mListViewAdapter.notifyDataSetChanged();
}

@Override
public void onSessionRenamed(TerminalSession renamedSession) {
if (!mIsVisible) return;
mListViewAdapter.notifyDataSetChanged();
}

@Override
public void onClipboardText(TerminalSession session, String text) {
if (!mIsVisible) return;
Expand Down Expand Up @@ -422,7 +456,20 @@ public void onBell(TerminalSession session) {
public void onColorsChanged(TerminalSession changedSession) {
if (getCurrentTermSession() == changedSession) updateBackgroundColor();
}

@Override
public void onAttach(TerminalSession attachedSession) {
if (!mIsVisible) return;
mListViewAdapter.notifyDataSetChanged();
}

@Override
public void onDetach(TerminalSession detachedSession) {
if (!mIsVisible) return;
mListViewAdapter.notifyDataSetChanged();
}
};
mTermService.mSessionChangeCallbacks.add(mSessionChangedCallback);

ListView listView = (ListView) findViewById(R.id.left_drawer_list);
mListViewAdapter = new ArrayAdapter<TerminalSession>(getApplicationContext(), R.layout.line_in_drawer, mTermService.getSessions()) {
Expand Down Expand Up @@ -464,8 +511,15 @@ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
}
int color = sessionRunning || sessionAtRow.getExitStatus() == 0 ? Color.BLACK : Color.RED;
firstLineView.setTextColor(color);
row.setEnabled(isEnabled(position));

return row;
}

@Override
public boolean isEnabled(int position) {
return !getItem(position).mAttached || getCurrentTermSession() == getItem(position);
}
};
listView.setAdapter(mListViewAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
Expand All @@ -485,7 +539,9 @@ public boolean onItemLongClick(AdapterView<?> parent, View view, final int posit
}
});

if (mTermService.getSessions().isEmpty()) {
TerminalSession sessionToAttach = mTermService.getFirstUnattachedSession();

if (sessionToAttach == null) {
if (mIsVisible) {
TermuxInstaller.setupIfNeeded(TermuxActivity.this, new Runnable() {
@Override
Expand Down Expand Up @@ -514,7 +570,7 @@ public void onClick(DialogInterface dialog, int which) {
finish();
}
} else {
switchToSession(getStoredCurrentSessionOrLast());
switchToSession(sessionToAttach);
}
}

Expand All @@ -535,7 +591,7 @@ void renameSession(final TerminalSession sessionToRename) {
@Override
public void onTextSet(String text) {
sessionToRename.mSessionName = text;
mListViewAdapter.notifyDataSetChanged();
mTermService.onSessionRenamed(sessionToRename);
}
}, -1, null, -1, null, null);
}
Expand All @@ -544,6 +600,13 @@ public void onTextSet(String text) {
public void onServiceDisconnected(ComponentName name) {
if (mTermService != null) {
// Respect being stopped from the TermuxService notification action.
TerminalSession currentSession = getCurrentTermSession();

if (currentSession != null) {
currentSession.mAttached = false;
mTermService.onDetach(currentSession);
}

finish();
}
}
Expand All @@ -560,7 +623,9 @@ public void onStart() {

if (mTermService != null) {
// The service has connected, but data may have changed since we were last in the foreground.
switchToSession(getStoredCurrentSessionOrLast());
if (getCurrentTermSession() == null) {
switchToSession(getStoredCurrentSessionOrLast());
}
mListViewAdapter.notifyDataSetChanged();
}

Expand Down Expand Up @@ -595,7 +660,9 @@ public void onDestroy() {
super.onDestroy();
if (mTermService != null) {
// Do not leave service with references to activity.
mTermService.mSessionChangeCallback = null;
mTermService.mSessionChangeCallbacks.remove(mSessionChangedCallback);
getCurrentTermSession().mAttached = false;
mTermService.onDetach(getCurrentTermSession());
mTermService = null;
}
unbindService(this);
Expand All @@ -620,9 +687,22 @@ void addNewSession(boolean failSafe, String sessionName) {
}
}

@TargetApi(Build.VERSION_CODES.N)
void addNewWindow() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N || !isInMultiWindowMode()) return;

Intent intent = new Intent(TermuxActivity.this, TermuxActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);
}

/** Try switching to session and note about it, but do nothing if already displaying the session. */
void switchToSession(TerminalSession session) {
TerminalSession oldSession = getCurrentTermSession();

if (mTerminalView.attachSession(session)) {
if(oldSession != null) mTermService.onDetach(oldSession);
mTermService.onAttach(session);
noteSessionInfo();
updateBackgroundColor();
}
Expand All @@ -648,7 +728,6 @@ void noteSessionInfo() {
TerminalSession session = getCurrentTermSession();
final int indexOfSession = mTermService.getSessions().indexOf(session);
showToast(toToastTitle(session), false);
mListViewAdapter.notifyDataSetChanged();
final ListView lv = ((ListView) findViewById(R.id.left_drawer_list));
lv.setItemChecked(indexOfSession, true);
lv.smoothScrollToPosition(indexOfSession);
Expand Down Expand Up @@ -857,18 +936,22 @@ void showToast(String text, boolean longDuration) {
public void removeFinishedSession(TerminalSession finishedSession) {
// Return pressed with finished session - remove it.
TermuxService service = mTermService;
service.removeTermSession(finishedSession);

TerminalSession unattachedSession = mTermService.getFirstUnattachedSession();

int index = service.removeTermSession(finishedSession);
mListViewAdapter.notifyDataSetChanged();
if (mTermService.getSessions().isEmpty()) {
if (unattachedSession == null) {
// There are no sessions to show, so finish the activity.
finish();
} else {
if (index >= service.getSessions().size()) {
index = service.getSessions().size() - 1;
}
switchToSession(service.getSessions().get(index));
switchToSession(unattachedSession);
}
}

@Override
@TargetApi(Build.VERSION_CODES.N)
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
findViewById(R.id.new_window_button).setVisibility(isInMultiWindowMode ? View.VISIBLE : View.GONE);
((LinearLayout) findViewById(R.id.drawer_buttons)).setOrientation(isInMultiWindowMode ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/com/termux/app/TermuxKeyListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ public boolean onKeyDown(int keyCode, KeyEvent e, TerminalSession currentSession
mActivity.renameSession(currentSession);
} else if (unicodeChar == 'c'/* create */) {
mActivity.addNewSession(false, null);
} else if (unicodeChar == 'w'/* window */) {
mActivity.addNewWindow();
} else if (unicodeChar == 'u' /* urls */) {
mActivity.showUrlSelection();
} else if (unicodeChar == 'v') {
Expand Down
Loading