Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92570bee06 | ||
|
|
05bb399893 | ||
|
|
831aa69da8 | ||
|
|
a56cba6843 | ||
|
|
9228982632 | ||
|
|
38114784f1 | ||
|
|
b805f1486c | ||
|
|
7d31b7f480 | ||
|
|
a0298285e3 | ||
|
|
538a1d5cdf | ||
|
|
f1e973f0d2 | ||
|
|
b467b68f7b | ||
|
|
b895cbbb1e | ||
|
|
fc30eba247 | ||
|
|
b1d4c0c7fe | ||
|
|
7fe5bd32c8 | ||
|
|
43bbef9a11 | ||
|
|
eaea0f74a5 | ||
|
|
cb13a5a531 | ||
|
|
d267843e36 | ||
|
|
5ca67dd885 | ||
|
|
6b0d531758 | ||
|
|
1b3283bd69 | ||
|
|
2820f6a7b8 | ||
|
|
8925ae67bb | ||
|
|
4066c5df42 | ||
|
|
20aac6aa72 | ||
|
|
e1f799f9a1 | ||
|
|
4479de4b9b | ||
|
|
3a8f53a54c | ||
|
|
2f04a6186b | ||
|
|
ad64dd7c3d | ||
|
|
dfc4595ec5 | ||
|
|
8c80efb904 | ||
|
|
564079c7e9 | ||
|
|
3bb2849a88 |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,3 +1,5 @@
|
|||||||
* text=auto
|
* text=auto
|
||||||
*.bat eol=crlf
|
*.bat eol=crlf
|
||||||
|
*.gradle eol=lf
|
||||||
|
*.mk eol=lf
|
||||||
*.sh eol=lf
|
*.sh eol=lf
|
||||||
|
|||||||
2
.github/FUNDING.yml
vendored
Normal file
2
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
patreon: termux
|
||||||
|
custom: https://paypal.me/fornwall
|
||||||
@@ -9,7 +9,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation "androidx.annotation:annotation:1.1.0"
|
implementation "androidx.annotation:annotation:1.1.0"
|
||||||
implementation "androidx.viewpager:viewpager:1.0.0"
|
implementation "androidx.viewpager:viewpager:1.0.0"
|
||||||
implementation "androidx.drawerlayout:drawerlayout:1.1.0"
|
implementation "androidx.drawerlayout:drawerlayout:1.1.1"
|
||||||
implementation project(":terminal-view")
|
implementation project(":terminal-view")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,8 +17,8 @@ android {
|
|||||||
applicationId "com.termux"
|
applicationId "com.termux"
|
||||||
minSdkVersion project.properties.minSdkVersion.toInteger()
|
minSdkVersion project.properties.minSdkVersion.toInteger()
|
||||||
targetSdkVersion project.properties.targetSdkVersion.toInteger()
|
targetSdkVersion project.properties.targetSdkVersion.toInteger()
|
||||||
versionCode 101
|
versionCode 106
|
||||||
versionName "0.101"
|
versionName "0.106"
|
||||||
|
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
ndkBuild {
|
ndkBuild {
|
||||||
@@ -64,6 +64,10 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
disable 'ProtectedPermissions'
|
||||||
|
}
|
||||||
|
|
||||||
testOptions {
|
testOptions {
|
||||||
unitTests {
|
unitTests {
|
||||||
includeAndroidResources = true
|
includeAndroidResources = true
|
||||||
@@ -72,8 +76,8 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation 'junit:junit:4.13'
|
testImplementation 'junit:junit:4.13.1'
|
||||||
testImplementation 'org.robolectric:robolectric:4.3.1'
|
testImplementation 'org.robolectric:robolectric:4.4'
|
||||||
}
|
}
|
||||||
|
|
||||||
task versionName {
|
task versionName {
|
||||||
@@ -133,11 +137,11 @@ clean {
|
|||||||
|
|
||||||
task downloadBootstraps(){
|
task downloadBootstraps(){
|
||||||
doLast {
|
doLast {
|
||||||
def version = 30
|
def version = 35
|
||||||
downloadBootstrap("aarch64", "7a90034285c614d23fa450547a5e2aec77d4242c9891ad662bf0c6fd3bd7ef4e", version)
|
downloadBootstrap("aarch64", "6707cc641cde13dc2f24e819cd8ca3f1a9a003577523c25beff72690588594f5", version)
|
||||||
downloadBootstrap("arm", "f030869ce9a43f84d88560d7ac5153ee4f7e517bca0b37ab01df3e1acba0fe37", version)
|
downloadBootstrap("arm", "eadc9afb52900dc744fdb39ed0c3dbb87ad8ce6190b27946467df7aeab353fa7", version)
|
||||||
downloadBootstrap("i686", "1ea9b63f21602231140d58a5545cfbc6bc2ded56ef2b3c31cba2759d913eef00", version)
|
downloadBootstrap("i686", "b674ef43c8388dd19e0d25b024b5792c8532ee0ddcc49f90c0716042724fa905", version)
|
||||||
downloadBootstrap("x86_64", "a50eb8a4dd02b7898bbd4a9653a25c14b56c1737409ce7f64110fd33c2c69382", version)
|
downloadBootstrap("x86_64", "86043eb76efededbdf5644686a899f4d762703fe18e23fb906a2482d593d7549", version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:extractNativeLibs="true"
|
android:extractNativeLibs="true"
|
||||||
@@ -81,16 +83,15 @@
|
|||||||
<data android:mimeType="text/*" />
|
<data android:mimeType="text/*" />
|
||||||
<data android:mimeType="video/*" />
|
<data android:mimeType="video/*" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<!-- Be more restrictive for viewing files, restricting ourselves to text files. -->
|
<!-- Accept multiple file types to let Termux be usable as generic file viewer. -->
|
||||||
<intent-filter tools:ignore="AppLinkUrlError">
|
<intent-filter tools:ignore="AppLinkUrlError">
|
||||||
<action android:name="android.intent.action.VIEW"/>
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:mimeType="application/*" />
|
||||||
|
<data android:mimeType="audio/*" />
|
||||||
|
<data android:mimeType="image/*" />
|
||||||
<data android:mimeType="text/*" />
|
<data android:mimeType="text/*" />
|
||||||
<data android:mimeType="application/*log*" />
|
<data android:mimeType="video/*" />
|
||||||
<data android:mimeType="application/json" />
|
|
||||||
<data android:mimeType="application/*xml*" />
|
|
||||||
<data android:mimeType="application/*latex*" />
|
|
||||||
<data android:mimeType="application/javascript" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ public final class BackgroundJob {
|
|||||||
environment.add("PATH= " + System.getenv("PATH"));
|
environment.add("PATH= " + System.getenv("PATH"));
|
||||||
} else {
|
} else {
|
||||||
environment.add("LANG=en_US.UTF-8");
|
environment.add("LANG=en_US.UTF-8");
|
||||||
environment.add("PATH=" + TermuxService.PREFIX_PATH + "/bin:" + TermuxService.PREFIX_PATH + "/bin/applets");
|
environment.add("PATH=" + TermuxService.PREFIX_PATH + "/bin");
|
||||||
environment.add("PWD=" + cwd);
|
environment.add("PWD=" + cwd);
|
||||||
environment.add("TMPDIR=" + TermuxService.PREFIX_PATH + "/tmp");
|
environment.add("TMPDIR=" + TermuxService.PREFIX_PATH + "/tmp");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
@@ -38,6 +39,7 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.view.autofill.AutofillManager;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
@@ -92,6 +94,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
private static final int CONTEXTMENU_STYLING_ID = 6;
|
private static final int CONTEXTMENU_STYLING_ID = 6;
|
||||||
private static final int CONTEXTMENU_HELP_ID = 8;
|
private static final int CONTEXTMENU_HELP_ID = 8;
|
||||||
private static final int CONTEXTMENU_TOGGLE_KEEP_SCREEN_ON = 9;
|
private static final int CONTEXTMENU_TOGGLE_KEEP_SCREEN_ON = 9;
|
||||||
|
private static final int CONTEXTMENU_AUTOFILL_ID = 10;
|
||||||
|
|
||||||
private static final int MAX_SESSIONS = 8;
|
private static final int MAX_SESSIONS = 8;
|
||||||
|
|
||||||
@@ -99,6 +102,8 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
|
|
||||||
private static final String RELOAD_STYLE_ACTION = "com.termux.app.reload_style";
|
private static final String RELOAD_STYLE_ACTION = "com.termux.app.reload_style";
|
||||||
|
|
||||||
|
private static final String BROADCAST_TERMUX_OPENED = "com.termux.app.OPENED";
|
||||||
|
|
||||||
/** The main view of the activity showing the terminal. Initialized in onCreate(). */
|
/** The main view of the activity showing the terminal. Initialized in onCreate(). */
|
||||||
@SuppressWarnings("NullableProblems")
|
@SuppressWarnings("NullableProblems")
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -322,6 +327,26 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
checkForFontAndColors();
|
checkForFontAndColors();
|
||||||
|
|
||||||
mBellSoundId = mBellSoundPool.load(this, R.raw.bell, 1);
|
mBellSoundId = mBellSoundPool.load(this, R.raw.bell, 1);
|
||||||
|
|
||||||
|
sendOpenedBroadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a broadcast notifying Termux app has been opened
|
||||||
|
*/
|
||||||
|
void sendOpenedBroadcast() {
|
||||||
|
Intent broadcast = new Intent(BROADCAST_TERMUX_OPENED);
|
||||||
|
List<ResolveInfo> matches = getPackageManager().queryBroadcastReceivers(broadcast, 0);
|
||||||
|
|
||||||
|
// send broadcast to registered Termux receivers
|
||||||
|
// this technique is needed to work around broadcast changes that Oreo introduced
|
||||||
|
for (ResolveInfo info : matches) {
|
||||||
|
Intent explicitBroadcast = new Intent(broadcast);
|
||||||
|
ComponentName cname = new ComponentName(info.activityInfo.applicationInfo.packageName,
|
||||||
|
info.activityInfo.name);
|
||||||
|
explicitBroadcast.setComponent(cname);
|
||||||
|
sendBroadcast(explicitBroadcast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleShowExtraKeys() {
|
void toggleShowExtraKeys() {
|
||||||
@@ -655,6 +680,12 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
|
|
||||||
menu.add(Menu.NONE, CONTEXTMENU_SELECT_URL_ID, Menu.NONE, R.string.select_url);
|
menu.add(Menu.NONE, CONTEXTMENU_SELECT_URL_ID, Menu.NONE, R.string.select_url);
|
||||||
menu.add(Menu.NONE, CONTEXTMENU_SHARE_TRANSCRIPT_ID, Menu.NONE, R.string.select_all_and_share);
|
menu.add(Menu.NONE, CONTEXTMENU_SHARE_TRANSCRIPT_ID, Menu.NONE, R.string.select_all_and_share);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
AutofillManager autofillManager = getSystemService(AutofillManager.class);
|
||||||
|
if (autofillManager != null && autofillManager.isEnabled()) {
|
||||||
|
menu.add(Menu.NONE, CONTEXTMENU_AUTOFILL_ID, Menu.NONE, R.string.autofill_password);
|
||||||
|
}
|
||||||
|
}
|
||||||
menu.add(Menu.NONE, CONTEXTMENU_RESET_TERMINAL_ID, Menu.NONE, R.string.reset_terminal);
|
menu.add(Menu.NONE, CONTEXTMENU_RESET_TERMINAL_ID, Menu.NONE, R.string.reset_terminal);
|
||||||
menu.add(Menu.NONE, CONTEXTMENU_KILL_PROCESS_ID, Menu.NONE, getResources().getString(R.string.kill_process, getCurrentTermSession().getPid())).setEnabled(currentSession.isRunning());
|
menu.add(Menu.NONE, CONTEXTMENU_KILL_PROCESS_ID, Menu.NONE, getResources().getString(R.string.kill_process, getCurrentTermSession().getPid())).setEnabled(currentSession.isRunning());
|
||||||
menu.add(Menu.NONE, CONTEXTMENU_STYLING_ID, Menu.NONE, R.string.style_terminal);
|
menu.add(Menu.NONE, CONTEXTMENU_STYLING_ID, Menu.NONE, R.string.style_terminal);
|
||||||
@@ -853,7 +884,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
// The startActivity() call is not documented to throw IllegalArgumentException.
|
// The startActivity() call is not documented to throw IllegalArgumentException.
|
||||||
// However, crash reporting shows that it sometimes does, so catch it here.
|
// However, crash reporting shows that it sometimes does, so catch it here.
|
||||||
new AlertDialog.Builder(this).setMessage(R.string.styling_not_installed)
|
new AlertDialog.Builder(this).setMessage(R.string.styling_not_installed)
|
||||||
.setPositiveButton(R.string.styling_install, (dialog, which) -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=com.termux.styling")))).setNegativeButton(android.R.string.cancel, null).show();
|
.setPositiveButton(R.string.styling_install, (dialog, which) -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://f-droid.org/en/packages/com.termux.styling/")))).setNegativeButton(android.R.string.cancel, null).show();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -870,6 +901,14 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case CONTEXTMENU_AUTOFILL_ID: {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
AutofillManager autofillManager = getSystemService(AutofillManager.class);
|
||||||
|
if (autofillManager != null && autofillManager.isEnabled()) {
|
||||||
|
autofillManager.requestAutofill(mTerminalView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return super.onContextItemSelected(item);
|
return super.onContextItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,10 +91,8 @@ public class TermuxDocumentsProvider extends DocumentsProvider {
|
|||||||
final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION);
|
final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION);
|
||||||
final File parent = getFileForDocId(parentDocumentId);
|
final File parent = getFileForDocId(parentDocumentId);
|
||||||
for (File file : parent.listFiles()) {
|
for (File file : parent.listFiles()) {
|
||||||
if (!file.getName().startsWith(".")) {
|
|
||||||
includeFile(result, null, file);
|
includeFile(result, null, file);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,8 +175,7 @@ public class TermuxDocumentsProvider extends DocumentsProvider {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
isInsideHome = true;
|
isInsideHome = true;
|
||||||
}
|
}
|
||||||
final boolean isHidden = file.getName().startsWith(".");
|
if (isInsideHome) {
|
||||||
if (isInsideHome && !isHidden) {
|
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
Collections.addAll(pending, file.listFiles());
|
Collections.addAll(pending, file.listFiles());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -19,7 +19,9 @@
|
|||||||
android:layout_marginLeft="3dp"
|
android:layout_marginLeft="3dp"
|
||||||
android:focusableInTouchMode="true"
|
android:focusableInTouchMode="true"
|
||||||
android:scrollbarThumbVertical="@drawable/terminal_scroll_shape"
|
android:scrollbarThumbVertical="@drawable/terminal_scroll_shape"
|
||||||
android:scrollbars="vertical" />
|
android:scrollbars="vertical"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:autofillHints="password" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/left_drawer"
|
android:id="@+id/left_drawer"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
android:imeOptions="actionSend|flagNoFullscreen"
|
android:imeOptions="actionSend|flagNoFullscreen"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
|
android:importantForAutofill="no"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textColorHighlight="@android:color/darker_gray"
|
android:textColorHighlight="@android:color/darker_gray"
|
||||||
android:paddingTop="0dp"
|
android:paddingTop="0dp"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
<string name="share_transcript_title">Terminal transcript</string>
|
<string name="share_transcript_title">Terminal transcript</string>
|
||||||
<string name="help">Help</string>
|
<string name="help">Help</string>
|
||||||
<string name="toggle_keep_screen_on">Keep screen on</string>
|
<string name="toggle_keep_screen_on">Keep screen on</string>
|
||||||
|
<string name="autofill_password">Autofill password</string>
|
||||||
|
|
||||||
<string name="bootstrap_installer_body">Installing…</string>
|
<string name="bootstrap_installer_body">Installing…</string>
|
||||||
<string name="bootstrap_error_title">Unable to install</string>
|
<string name="bootstrap_error_title">Unable to install</string>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ buildscript {
|
|||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
classpath 'com.android.tools.build:gradle:4.1.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,5 +17,5 @@ android.useAndroidX=true
|
|||||||
|
|
||||||
minSdkVersion=24
|
minSdkVersion=24
|
||||||
targetSdkVersion=28
|
targetSdkVersion=28
|
||||||
ndkVersion=21.3.6528147
|
ndkVersion=22.0.7026061
|
||||||
compileSdkVersion=28
|
compileSdkVersion=28
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.jfrog.bintray" version "1.7.3"
|
id "com.jfrog.bintray" version "1.8.5"
|
||||||
id "com.github.dcendents.android-maven" version "2.0"
|
id "com.github.dcendents.android-maven" version "2.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
@@ -11,8 +11,8 @@ ext {
|
|||||||
libraryName = 'TerminalEmulator'
|
libraryName = 'TerminalEmulator'
|
||||||
artifact = 'terminal-emulator'
|
artifact = 'terminal-emulator'
|
||||||
libraryDescription = 'The terminal emulator used in Termux'
|
libraryDescription = 'The terminal emulator used in Termux'
|
||||||
siteUrl = 'https://github.com/termux/termux'
|
siteUrl = 'https://github.com/termux/termux-app'
|
||||||
gitUrl = 'https://github.com/termux/termux.git'
|
gitUrl = 'https://github.com/termux/termux-app.git'
|
||||||
libraryVersion = '0.52'
|
libraryVersion = '0.52'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +52,10 @@ android {
|
|||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testOptions {
|
||||||
|
unitTests.returnDefaultValues = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(Test) {
|
tasks.withType(Test) {
|
||||||
@@ -61,7 +65,7 @@ tasks.withType(Test) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation 'junit:junit:4.13'
|
testImplementation 'junit:junit:4.13.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: '../scripts/bintray-publish.gradle'
|
apply from: '../scripts/bintray-publish.gradle'
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ public class CursorAndScreenTest extends TerminalTestCase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* See comments on horizontal tab handling in TerminalEmulator.java.
|
* See comments on horizontal tab handling in TerminalEmulator.java.
|
||||||
*
|
* <p/>
|
||||||
* We do not want to color already written cells when tabbing over them.
|
* We do not want to color already written cells when tabbing over them.
|
||||||
*/
|
*/
|
||||||
public void DISABLED_testHorizontalTabColorsBackground() {
|
public void DISABLED_testHorizontalTabColorsBackground() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.jfrog.bintray" version "1.7.3"
|
id "com.jfrog.bintray" version "1.8.5"
|
||||||
id "com.github.dcendents.android-maven" version "2.0"
|
id "com.github.dcendents.android-maven" version "2.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
@@ -11,8 +11,8 @@ ext {
|
|||||||
libraryName = 'TerminalView'
|
libraryName = 'TerminalView'
|
||||||
artifact = 'terminal-view'
|
artifact = 'terminal-view'
|
||||||
libraryDescription = 'The terminal view used in Termux'
|
libraryDescription = 'The terminal view used in Termux'
|
||||||
siteUrl = 'https://github.com/termux/termux'
|
siteUrl = 'https://github.com/termux/termux-app'
|
||||||
gitUrl = 'https://github.com/termux/termux.git'
|
gitUrl = 'https://github.com/termux/termux-app.git'
|
||||||
libraryVersion = '0.50'
|
libraryVersion = '0.50'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation 'junit:junit:4.13'
|
testImplementation 'junit:junit:4.13.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: '../scripts/bintray-publish.gradle'
|
apply from: '../scripts/bintray-publish.gradle'
|
||||||
|
|||||||
@@ -31,12 +31,15 @@ import android.view.ViewParent;
|
|||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
|
import android.view.autofill.AutofillValue;
|
||||||
import android.view.inputmethod.BaseInputConnection;
|
import android.view.inputmethod.BaseInputConnection;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputConnection;
|
import android.view.inputmethod.InputConnection;
|
||||||
import android.widget.PopupWindow;
|
import android.widget.PopupWindow;
|
||||||
import android.widget.Scroller;
|
import android.widget.Scroller;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
import com.termux.terminal.EmulatorDebug;
|
import com.termux.terminal.EmulatorDebug;
|
||||||
import com.termux.terminal.KeyHandler;
|
import com.termux.terminal.KeyHandler;
|
||||||
import com.termux.terminal.TerminalBuffer;
|
import com.termux.terminal.TerminalBuffer;
|
||||||
@@ -252,20 +255,7 @@ public final class TerminalView extends View {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||||
File propsFile = new File(getContext().getFilesDir() + "/home/.termux/termux.properties");
|
Properties props = getProperties();
|
||||||
if (!propsFile.exists())
|
|
||||||
propsFile = new File(getContext().getFilesDir() + "/home/.config/termux/termux.properties");
|
|
||||||
|
|
||||||
Properties props = new Properties();
|
|
||||||
try {
|
|
||||||
if (propsFile.isFile() && propsFile.canRead()) {
|
|
||||||
try (FileInputStream in = new FileInputStream(propsFile)) {
|
|
||||||
props.load(new InputStreamReader(in, StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("termux", "Error loading props", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.getProperty("enforce-char-based-input", "false").equals("true")) {
|
if (props.getProperty("enforce-char-based-input", "false").equals("true")) {
|
||||||
// Some keyboards seems do not reset the internal state on TYPE_NULL.
|
// Some keyboards seems do not reset the internal state on TYPE_NULL.
|
||||||
@@ -549,6 +539,8 @@ public final class TerminalView extends View {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
|
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
|
||||||
|
Properties props = getProperties();
|
||||||
|
|
||||||
if (LOG_KEY_EVENTS)
|
if (LOG_KEY_EVENTS)
|
||||||
Log.i(EmulatorDebug.LOG_TAG, "onKeyPreIme(keyCode=" + keyCode + ", event=" + event + ")");
|
Log.i(EmulatorDebug.LOG_TAG, "onKeyPreIme(keyCode=" + keyCode + ", event=" + event + ")");
|
||||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||||
@@ -564,6 +556,11 @@ public final class TerminalView extends View {
|
|||||||
return onKeyUp(keyCode, event);
|
return onKeyUp(keyCode, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (props.getProperty("ctrl-space-workaround", "false").equals("true") &&
|
||||||
|
keyCode == KeyEvent.KEYCODE_SPACE && event.isCtrlPressed()) {
|
||||||
|
/* ctrl + space does not work on some ROMs without this workaround.
|
||||||
|
However, this breaks it on devices where it works out of the box. */
|
||||||
|
return onKeyDown(keyCode, event);
|
||||||
}
|
}
|
||||||
return super.onKeyPreIme(keyCode, event);
|
return super.onKeyPreIme(keyCode, event);
|
||||||
}
|
}
|
||||||
@@ -1194,7 +1191,7 @@ public final class TerminalView extends View {
|
|||||||
final ActionMode.Callback callback = new ActionMode.Callback() {
|
final ActionMode.Callback callback = new ActionMode.Callback() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||||
int show = MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT;
|
int show = MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT;
|
||||||
|
|
||||||
ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
menu.add(Menu.NONE, 1, Menu.NONE, R.string.copy_text).setShowAsAction(show);
|
menu.add(Menu.NONE, 1, Menu.NONE, R.string.copy_text).setShowAsAction(show);
|
||||||
@@ -1540,4 +1537,52 @@ public final class TerminalView extends View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Properties getProperties() {
|
||||||
|
File propsFile;
|
||||||
|
Properties props = new Properties();
|
||||||
|
String possiblePropLocations[] = {
|
||||||
|
getContext().getFilesDir() + "/home/.termux/termux.properties",
|
||||||
|
getContext().getFilesDir() + "/home/.config/termux/termux.properties"
|
||||||
|
};
|
||||||
|
|
||||||
|
propsFile = new File(possiblePropLocations[0]);
|
||||||
|
int i = 0;
|
||||||
|
while (!propsFile.exists() && i < possiblePropLocations.length) {
|
||||||
|
propsFile = new File(possiblePropLocations[i]);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (propsFile.isFile() && propsFile.canRead()) {
|
||||||
|
try (FileInputStream in = new FileInputStream(propsFile)) {
|
||||||
|
props.load(new InputStreamReader(in, StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("termux", "Error loading props", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
@Override
|
||||||
|
public void autofill(AutofillValue value) {
|
||||||
|
if (value.isText()) {
|
||||||
|
mTermSession.write(value.getTextValue().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
@Override
|
||||||
|
public int getAutofillType() {
|
||||||
|
return AUTOFILL_TYPE_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
@Override
|
||||||
|
public AutofillValue getAutofillValue() {
|
||||||
|
return AutofillValue.forText("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user