mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 10:45:23 +08:00
Allow users to enable terminal cursor blinking with termux.properties
This `terminal-cursor-blink-rate` key can be used to enable terminal cursor blinking. The user can set an int value between `100` and `2000` which will be used as blink rate in millisecond. The default value is `0`, which disables cursor blinking. So adding an entry like `terminal-cursor-blink-rate=600` to `~/termux.properties` file will make the cursor attempt to blink every 600ms. Running `termux-reload-settings` command will also update the cursor blinking rate instantaneously if changed. A background thread is used to control the blinking by toggling the cursor visibility and then invalidating the view every x milliseconds set. This will have a performance impact, so use wisely and at your own risk. If the cursor itself is disabled, which is controlled by whether DECSET_BIT_CURSOR_ENABLED (DECSET 25, DECTCEM), then blinking will be automatically disabled. You can enable the cursor with `tput cnorm` or `echo -e '\e[?25h'` and disable it with `tput civis` or `echo -e '\e[?25l'`. Note that you can also change the cursor color by adding `cursor` property to `~/colors.properties` file, like `cursor=#FFFFFF` for a white cursor. The `TermuxPropertyConstants` class has been updated to `v0.9.0`. Check its Changelog sections for info on changes. Closes #153
This commit is contained in:
@@ -257,6 +257,9 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
if (mIsInvalidState) return;
|
if (mIsInvalidState) return;
|
||||||
|
|
||||||
mTermuxTerminalViewClient.setSoftKeyboardState(true, false);
|
mTermuxTerminalViewClient.setSoftKeyboardState(true, false);
|
||||||
|
|
||||||
|
// Start terminal cursor blinking if enabled
|
||||||
|
mTermuxTerminalViewClient.setTerminalCursorBlinkerState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -330,6 +333,9 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
// {@link #onStart} if needed.
|
// {@link #onStart} if needed.
|
||||||
mTermuxTerminalSessionClient.setCurrentStoredSession();
|
mTermuxTerminalSessionClient.setCurrentStoredSession();
|
||||||
|
|
||||||
|
// Stop terminal cursor blinking if enabled
|
||||||
|
mTermuxTerminalViewClient.setTerminalCursorBlinkerState(false);
|
||||||
|
|
||||||
unregisterTermuxActivityBroadcastReceiever();
|
unregisterTermuxActivityBroadcastReceiever();
|
||||||
getDrawer().closeDrawers();
|
getDrawer().closeDrawers();
|
||||||
}
|
}
|
||||||
@@ -799,6 +805,9 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
|
|
||||||
mTermuxTerminalViewClient.setSoftKeyboardState(false, true);
|
mTermuxTerminalViewClient.setSoftKeyboardState(false, true);
|
||||||
|
|
||||||
|
mTermuxTerminalViewClient.setTerminalCursorBlinkerState(true);
|
||||||
|
|
||||||
|
|
||||||
// To change the activity and drawer theme, activity needs to be recreated.
|
// To change the activity and drawer theme, activity needs to be recreated.
|
||||||
// But this will destroy the activity, and will call the onCreate() again.
|
// But this will destroy the activity, and will call the onCreate() again.
|
||||||
// We need to investigate if enabling this is wise, since all stored variables and
|
// We need to investigate if enabling this is wise, since all stored variables and
|
||||||
|
@@ -137,6 +137,19 @@ public class TermuxTerminalSessionClient extends TermuxTerminalSessionClientBase
|
|||||||
updateBackgroundColor();
|
updateBackgroundColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTerminalCursorStateChange(boolean enabled) {
|
||||||
|
// Do not start cursor blinking thread if activity is not visible
|
||||||
|
if (enabled && !mActivity.isVisible()) {
|
||||||
|
Logger.logVerbose(LOG_TAG, "Ignoring call to start cursor blinking since activity is not visible");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If cursor is to enabled now, then start cursor blinking if blinking is enabled
|
||||||
|
// otherwise stop cursor blinking
|
||||||
|
mActivity.getTerminalView().setTerminalCursorBlinkerState(enabled, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Try switching to session. */
|
/** Try switching to session. */
|
||||||
|
@@ -427,6 +427,18 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void setTerminalCursorBlinkerState(boolean start) {
|
||||||
|
if (start) {
|
||||||
|
// Set/Update the cursor blinking rate
|
||||||
|
mActivity.getTerminalView().setTerminalCursorBlinkerRate(mActivity.getProperties().getTerminalCursorBlinkRate());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the new state of cursor blinker
|
||||||
|
mActivity.getTerminalView().setTerminalCursorBlinkerState(start, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void shareSessionTranscript() {
|
public void shareSessionTranscript() {
|
||||||
TerminalSession session = mActivity.getCurrentSession();
|
TerminalSession session = mActivity.getCurrentSession();
|
||||||
if (session == null) return;
|
if (session == null) return;
|
||||||
|
@@ -108,8 +108,8 @@ public final class TerminalEmulator {
|
|||||||
* characters received when the cursor is at the right border of the page replace characters already on the page."
|
* characters received when the cursor is at the right border of the page replace characters already on the page."
|
||||||
*/
|
*/
|
||||||
private static final int DECSET_BIT_AUTOWRAP = 1 << 3;
|
private static final int DECSET_BIT_AUTOWRAP = 1 << 3;
|
||||||
/** DECSET 25 - if the cursor should be visible, {@link #isShowingCursor()}. */
|
/** DECSET 25 - if the cursor should be enabled, {@link #isCursorEnabled()}. */
|
||||||
private static final int DECSET_BIT_SHOWING_CURSOR = 1 << 4;
|
private static final int DECSET_BIT_CURSOR_ENABLED = 1 << 4;
|
||||||
private static final int DECSET_BIT_APPLICATION_KEYPAD = 1 << 5;
|
private static final int DECSET_BIT_APPLICATION_KEYPAD = 1 << 5;
|
||||||
/** DECSET 1000 - if to report mouse press&release events. */
|
/** DECSET 1000 - if to report mouse press&release events. */
|
||||||
private static final int DECSET_BIT_MOUSE_TRACKING_PRESS_RELEASE = 1 << 6;
|
private static final int DECSET_BIT_MOUSE_TRACKING_PRESS_RELEASE = 1 << 6;
|
||||||
@@ -205,6 +205,18 @@ public final class TerminalEmulator {
|
|||||||
*/
|
*/
|
||||||
private boolean mAboutToAutoWrap;
|
private boolean mAboutToAutoWrap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the cursor blinking is enabled. It requires cursor itself to be enabled, which is controlled
|
||||||
|
* byt whether {@link #DECSET_BIT_CURSOR_ENABLED} bit is set or not.
|
||||||
|
*/
|
||||||
|
private boolean mCursorBlinkingEnabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If currently cursor should be in a visible state or not if {@link #mCursorBlinkingEnabled}
|
||||||
|
* is {@code true}.
|
||||||
|
*/
|
||||||
|
private boolean mCursorBlinkState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current foreground and background colors. Can either be a color index in [0,259] or a truecolor (24-bit) value.
|
* Current foreground and background colors. Can either be a color index in [0,259] or a truecolor (24-bit) value.
|
||||||
* For a 24-bit value the top byte (0xff000000) is set.
|
* For a 24-bit value the top byte (0xff000000) is set.
|
||||||
@@ -261,7 +273,7 @@ public final class TerminalEmulator {
|
|||||||
case 7:
|
case 7:
|
||||||
return DECSET_BIT_AUTOWRAP;
|
return DECSET_BIT_AUTOWRAP;
|
||||||
case 25:
|
case 25:
|
||||||
return DECSET_BIT_SHOWING_CURSOR;
|
return DECSET_BIT_CURSOR_ENABLED;
|
||||||
case 66:
|
case 66:
|
||||||
return DECSET_BIT_APPLICATION_KEYPAD;
|
return DECSET_BIT_APPLICATION_KEYPAD;
|
||||||
case 69:
|
case 69:
|
||||||
@@ -381,9 +393,27 @@ public final class TerminalEmulator {
|
|||||||
return isDecsetInternalBitSet(DECSET_BIT_REVERSE_VIDEO);
|
return isDecsetInternalBitSet(DECSET_BIT_REVERSE_VIDEO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShowingCursor() {
|
|
||||||
return isDecsetInternalBitSet(DECSET_BIT_SHOWING_CURSOR);
|
|
||||||
|
public boolean isCursorEnabled() {
|
||||||
|
return isDecsetInternalBitSet(DECSET_BIT_CURSOR_ENABLED);
|
||||||
}
|
}
|
||||||
|
public boolean shouldCursorBeVisible() {
|
||||||
|
if (!isCursorEnabled())
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return mCursorBlinkingEnabled ? mCursorBlinkState : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCursorBlinkingEnabled(boolean cursorBlinkingEnabled) {
|
||||||
|
this.mCursorBlinkingEnabled = cursorBlinkingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCursorBlinkState(boolean cursorBlinkState) {
|
||||||
|
this.mCursorBlinkState = cursorBlinkState;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isKeypadApplicationMode() {
|
public boolean isKeypadApplicationMode() {
|
||||||
return isDecsetInternalBitSet(DECSET_BIT_APPLICATION_KEYPAD);
|
return isDecsetInternalBitSet(DECSET_BIT_APPLICATION_KEYPAD);
|
||||||
@@ -1054,7 +1084,10 @@ public final class TerminalEmulator {
|
|||||||
case 8: // Auto-repeat Keys (DECARM). Do not implement.
|
case 8: // Auto-repeat Keys (DECARM). Do not implement.
|
||||||
case 9: // X10 mouse reporting - outdated. Do not implement.
|
case 9: // X10 mouse reporting - outdated. Do not implement.
|
||||||
case 12: // Control cursor blinking - ignore.
|
case 12: // Control cursor blinking - ignore.
|
||||||
case 25: // Hide/show cursor - no action needed, renderer will check with isShowingCursor().
|
case 25: // Hide/show cursor - no action needed, renderer will check with shouldCursorBeVisible().
|
||||||
|
if (mClient != null)
|
||||||
|
mClient.onTerminalCursorStateChange(setting);
|
||||||
|
break;
|
||||||
case 40: // Allow 80 => 132 Mode, ignore.
|
case 40: // Allow 80 => 132 Mode, ignore.
|
||||||
case 45: // TODO: Reverse wrap-around. Implement???
|
case 45: // TODO: Reverse wrap-around. Implement???
|
||||||
case 66: // Application keypad (DECNKM).
|
case 66: // Application keypad (DECNKM).
|
||||||
@@ -2318,7 +2351,7 @@ public final class TerminalEmulator {
|
|||||||
mCurrentDecSetFlags = 0;
|
mCurrentDecSetFlags = 0;
|
||||||
// Initial wrap-around is not accurate but makes terminal more useful, especially on a small screen:
|
// Initial wrap-around is not accurate but makes terminal more useful, especially on a small screen:
|
||||||
setDecsetinternalBit(DECSET_BIT_AUTOWRAP, true);
|
setDecsetinternalBit(DECSET_BIT_AUTOWRAP, true);
|
||||||
setDecsetinternalBit(DECSET_BIT_SHOWING_CURSOR, true);
|
setDecsetinternalBit(DECSET_BIT_CURSOR_ENABLED, true);
|
||||||
mSavedDecSetFlags = mSavedStateMain.mSavedDecFlags = mSavedStateAlt.mSavedDecFlags = mCurrentDecSetFlags;
|
mSavedDecSetFlags = mSavedStateMain.mSavedDecFlags = mSavedStateAlt.mSavedDecFlags = mCurrentDecSetFlags;
|
||||||
|
|
||||||
// XXX: Should we set terminal driver back to IUTF8 with termios?
|
// XXX: Should we set terminal driver back to IUTF8 with termios?
|
||||||
|
@@ -19,6 +19,8 @@ public interface TerminalSessionClient {
|
|||||||
|
|
||||||
void onColorsChanged(TerminalSession session);
|
void onColorsChanged(TerminalSession session);
|
||||||
|
|
||||||
|
void onTerminalCursorStateChange(boolean state);
|
||||||
|
|
||||||
|
|
||||||
void logError(String tag, String message);
|
void logError(String tag, String message);
|
||||||
|
|
||||||
|
@@ -16,23 +16,23 @@ package com.termux.terminal;
|
|||||||
public class DecSetTest extends TerminalTestCase {
|
public class DecSetTest extends TerminalTestCase {
|
||||||
|
|
||||||
/** DECSET 25, DECTCEM, controls visibility of the cursor. */
|
/** DECSET 25, DECTCEM, controls visibility of the cursor. */
|
||||||
public void testShowHideCursor() {
|
public void testEnableDisableCursor() {
|
||||||
withTerminalSized(3, 3);
|
withTerminalSized(3, 3);
|
||||||
assertTrue("Initially the cursor should be visible", mTerminal.isShowingCursor());
|
assertTrue("Initially the cursor should be enabled", mTerminal.isCursorEnabled());
|
||||||
enterString("\033[?25l"); // Hide Cursor (DECTCEM).
|
enterString("\033[?25l"); // Disable Cursor (DECTCEM).
|
||||||
assertFalse(mTerminal.isShowingCursor());
|
assertFalse(mTerminal.isCursorEnabled());
|
||||||
enterString("\033[?25h"); // Show Cursor (DECTCEM).
|
enterString("\033[?25h"); // Enable Cursor (DECTCEM).
|
||||||
assertTrue(mTerminal.isShowingCursor());
|
assertTrue(mTerminal.isCursorEnabled());
|
||||||
|
|
||||||
enterString("\033[?25l"); // Hide Cursor (DECTCEM), again.
|
enterString("\033[?25l"); // Disable Cursor (DECTCEM), again.
|
||||||
assertFalse(mTerminal.isShowingCursor());
|
assertFalse(mTerminal.isCursorEnabled());
|
||||||
mTerminal.reset();
|
mTerminal.reset();
|
||||||
assertTrue("Resetting the terminal should show the cursor", mTerminal.isShowingCursor());
|
assertTrue("Resetting the terminal should enable the cursor", mTerminal.isCursorEnabled());
|
||||||
|
|
||||||
enterString("\033[?25l");
|
enterString("\033[?25l");
|
||||||
assertFalse(mTerminal.isShowingCursor());
|
assertFalse(mTerminal.isCursorEnabled());
|
||||||
enterString("\033c"); // RIS resetting should reveal cursor.
|
enterString("\033c"); // RIS resetting should enabled cursor.
|
||||||
assertTrue(mTerminal.isShowingCursor());
|
assertTrue(mTerminal.isCursorEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DECSET 2004, controls bracketed paste mode. */
|
/** DECSET 2004, controls bracketed paste mode. */
|
||||||
|
@@ -61,7 +61,7 @@ public final class TerminalRenderer {
|
|||||||
final int columns = mEmulator.mColumns;
|
final int columns = mEmulator.mColumns;
|
||||||
final int cursorCol = mEmulator.getCursorCol();
|
final int cursorCol = mEmulator.getCursorCol();
|
||||||
final int cursorRow = mEmulator.getCursorRow();
|
final int cursorRow = mEmulator.getCursorRow();
|
||||||
final boolean cursorVisible = mEmulator.isShowingCursor();
|
final boolean cursorVisible = mEmulator.shouldCursorBeVisible();
|
||||||
final TerminalBuffer screen = mEmulator.getScreen();
|
final TerminalBuffer screen = mEmulator.getScreen();
|
||||||
final int[] palette = mEmulator.mColors.mCurrentColors;
|
final int[] palette = mEmulator.mColors.mCurrentColors;
|
||||||
final int cursorShape = mEmulator.getCursorStyle();
|
final int cursorShape = mEmulator.getCursorStyle();
|
||||||
|
@@ -8,6 +8,8 @@ import android.content.Context;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -52,6 +54,14 @@ public final class TerminalView extends View {
|
|||||||
|
|
||||||
private TextSelectionCursorController mTextSelectionCursorController;
|
private TextSelectionCursorController mTextSelectionCursorController;
|
||||||
|
|
||||||
|
private Handler mTerminalCursorBlinkerHandler;
|
||||||
|
private TerminalCursorBlinkerThread mTerminalCursorBlinkerThread;
|
||||||
|
private int mTerminalCursorBlinkerRate;
|
||||||
|
public static final int TERMINAL_CURSOR_BLINK_RATE_MIN = 100;
|
||||||
|
public static final int TERMINAL_CURSOR_BLINK_RATE_MAX = 2000;
|
||||||
|
|
||||||
|
private boolean mRendering;
|
||||||
|
|
||||||
/** 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;
|
int mTopRow;
|
||||||
int[] mDefaultSelectors = new int[]{-1,-1,-1,-1};
|
int[] mDefaultSelectors = new int[]{-1,-1,-1,-1};
|
||||||
@@ -209,6 +219,8 @@ public final class TerminalView extends View {
|
|||||||
mAccessibilityEnabled = am.isEnabled();
|
mAccessibilityEnabled = am.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param client The {@link TerminalViewClient} interface implementation to allow
|
* @param client The {@link TerminalViewClient} interface implementation to allow
|
||||||
* for communication between {@link TerminalView} and its client.
|
* for communication between {@link TerminalView} and its client.
|
||||||
@@ -218,7 +230,7 @@ public final class TerminalView extends View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets terminal view key logging is enabled or not.
|
* Sets whether terminal view key logging is enabled or not.
|
||||||
*
|
*
|
||||||
* @param value The boolean value that defines the state.
|
* @param value The boolean value that defines the state.
|
||||||
*/
|
*/
|
||||||
@@ -226,6 +238,8 @@ public final class TerminalView extends View {
|
|||||||
TERMINAL_VIEW_KEY_LOGGING_ENABLED = value;
|
TERMINAL_VIEW_KEY_LOGGING_ENABLED = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach a {@link TerminalSession} to this view.
|
* Attach a {@link TerminalSession} to this view.
|
||||||
*
|
*
|
||||||
@@ -755,7 +769,10 @@ public final class TerminalView extends View {
|
|||||||
if (mTextSelectionCursorController != null) {
|
if (mTextSelectionCursorController != null) {
|
||||||
mTextSelectionCursorController.getSelectors(sel);
|
mTextSelectionCursorController.getSelectors(sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mRendering = true;
|
||||||
mRenderer.render(mEmulator, canvas, mTopRow, sel[0], sel[1], sel[2], sel[3]);
|
mRenderer.render(mEmulator, canvas, mTopRow, sel[0], sel[1], sel[2], sel[3]);
|
||||||
|
mRendering = false;
|
||||||
|
|
||||||
// render the text selection handles
|
// render the text selection handles
|
||||||
renderTextSelection();
|
renderTextSelection();
|
||||||
@@ -799,7 +816,6 @@ public final class TerminalView extends View {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define functions required for AutoFill API
|
* Define functions required for AutoFill API
|
||||||
*/
|
*/
|
||||||
@@ -825,6 +841,98 @@ public final class TerminalView extends View {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set terminal cursor blinker rate. It must be between {@link #TERMINAL_CURSOR_BLINK_RATE_MIN}
|
||||||
|
* and {@link #TERMINAL_CURSOR_BLINK_RATE_MAX}.
|
||||||
|
*
|
||||||
|
* @param blinkRate The value to set.
|
||||||
|
*/
|
||||||
|
public void setTerminalCursorBlinkerRate(int blinkRate) {
|
||||||
|
mTerminalCursorBlinkerRate = blinkRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether cursor blinking should be started or stopped. Cursor blinking will only be
|
||||||
|
* started if {@link #mTerminalCursorBlinkerRate} does not equal 0 and is between
|
||||||
|
* {@link #TERMINAL_CURSOR_BLINK_RATE_MIN} and {@link #TERMINAL_CURSOR_BLINK_RATE_MAX}.
|
||||||
|
*
|
||||||
|
* @param start If cursor blinking should be started or stopped.
|
||||||
|
* @param startOnlyIfCursorEnabled If set to {@code true}, then it will also be checked if the
|
||||||
|
* cursor is even enabled by {@link TerminalEmulator} before
|
||||||
|
* starting the cursor blinking thread.
|
||||||
|
*/
|
||||||
|
public synchronized void setTerminalCursorBlinkerState(boolean start, boolean startOnlyIfCursorEnabled) {
|
||||||
|
// Stop any existing cursor blinker threads
|
||||||
|
stopTerminalCursorBlinkerThread();
|
||||||
|
|
||||||
|
if (mEmulator == null) return;
|
||||||
|
|
||||||
|
mEmulator.setCursorBlinkingEnabled(false);
|
||||||
|
|
||||||
|
if (start) {
|
||||||
|
// If cursor blinking is not enabled
|
||||||
|
if (mTerminalCursorBlinkerRate == 0) {
|
||||||
|
mClient.logVerbose(LOG_TAG, "Cursor blinking is not enabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If cursor blinking rate is not valid
|
||||||
|
else if (mTerminalCursorBlinkerRate < TERMINAL_CURSOR_BLINK_RATE_MIN || mTerminalCursorBlinkerRate > TERMINAL_CURSOR_BLINK_RATE_MAX) {
|
||||||
|
mClient.logError(LOG_TAG, "startCursorBlinkerThread: The cursor blink rate must be in between " + TERMINAL_CURSOR_BLINK_RATE_MIN + "-" + TERMINAL_CURSOR_BLINK_RATE_MAX + ": " + mTerminalCursorBlinkerRate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If cursor is not enabled
|
||||||
|
else if (startOnlyIfCursorEnabled && ! mEmulator.isCursorEnabled()) {
|
||||||
|
mClient.logVerbose(LOG_TAG, "Ignoring call to start cursor blinking since cursor is not enabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start cursor blinker thread
|
||||||
|
mClient.logVerbose(LOG_TAG, "Starting cursor blinker thread with the blink rate: " + mTerminalCursorBlinkerRate);
|
||||||
|
if (mTerminalCursorBlinkerHandler == null) mTerminalCursorBlinkerHandler = new Handler(Looper.getMainLooper());
|
||||||
|
mTerminalCursorBlinkerThread = new TerminalCursorBlinkerThread(mTerminalCursorBlinkerRate);
|
||||||
|
mEmulator.setCursorBlinkingEnabled(true);
|
||||||
|
mTerminalCursorBlinkerThread.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the terminal cursor blinker thread
|
||||||
|
*/
|
||||||
|
private void stopTerminalCursorBlinkerThread() {
|
||||||
|
if (mTerminalCursorBlinkerHandler != null && mTerminalCursorBlinkerThread != null) {
|
||||||
|
mClient.logVerbose(LOG_TAG, "Stopping cursor blinker thread");
|
||||||
|
mTerminalCursorBlinkerHandler.removeCallbacks(mTerminalCursorBlinkerThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TerminalCursorBlinkerThread implements Runnable {
|
||||||
|
int mBlinkRate;
|
||||||
|
boolean mCursorVisible;
|
||||||
|
|
||||||
|
public TerminalCursorBlinkerThread(int blinkRate) {
|
||||||
|
mBlinkRate = blinkRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
if (mEmulator != null) {
|
||||||
|
mCursorVisible = !mCursorVisible;
|
||||||
|
// Toggle the blink state and then invalidate() the view so
|
||||||
|
// that onDraw() is called, which then calls TerminalRenderer.render()
|
||||||
|
// which checks with TerminalEmulator.shouldCursorBeVisible() to decide whether
|
||||||
|
// to draw the cursor or not
|
||||||
|
mEmulator.setCursorBlinkState(mCursorVisible);
|
||||||
|
if (!mRendering)
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// Recall the Runnable after mBlinkRate milliseconds to toggle the blink state
|
||||||
|
mTerminalCursorBlinkerHandler.postDelayed(mTerminalCursorBlinkerThread, mBlinkRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define functions required for text selection and its handles.
|
* Define functions required for text selection and its handles.
|
||||||
@@ -920,7 +1028,6 @@ public final class TerminalView extends View {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define functions required for long hold toolbar.
|
* Define functions required for long hold toolbar.
|
||||||
*/
|
*/
|
||||||
|
@@ -10,7 +10,7 @@ import java.util.HashSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Version: v0.8.0
|
* Version: v0.9.0
|
||||||
*
|
*
|
||||||
* Changelog
|
* Changelog
|
||||||
*
|
*
|
||||||
@@ -41,6 +41,10 @@ import java.util.Set;
|
|||||||
* - Change the `KEY_USE_BACK_KEY_AS_ESCAPE_KEY` and `KEY_VIRTUAL_VOLUME_KEYS_DISABLED` booleans
|
* - Change the `KEY_USE_BACK_KEY_AS_ESCAPE_KEY` and `KEY_VIRTUAL_VOLUME_KEYS_DISABLED` booleans
|
||||||
* to `KEY_BACK_KEY_BEHAVIOUR` and `KEY_VOLUME_KEYS_BEHAVIOUR` String internal values.
|
* to `KEY_BACK_KEY_BEHAVIOUR` and `KEY_VOLUME_KEYS_BEHAVIOUR` String internal values.
|
||||||
* - Renamed `SOFT_KEYBOARD_TOGGLE_BEHAVIOUR` to `KEY_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR`.
|
* - Renamed `SOFT_KEYBOARD_TOGGLE_BEHAVIOUR` to `KEY_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR`.
|
||||||
|
*
|
||||||
|
* - 0.9.0 (2021-05-14)
|
||||||
|
* - Add `*KEY_TERMINAL_CURSOR_BLINK_RATE*`.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,6 +119,14 @@ public final class TermuxPropertyConstants {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Defines the key for the terminal cursor blink rate */
|
||||||
|
public static final String KEY_TERMINAL_CURSOR_BLINK_RATE = "terminal-cursor-blink-rate"; // Default: "terminal-cursor-blink-rate"
|
||||||
|
public static final int IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN = 100;
|
||||||
|
public static final int IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX = 2000;
|
||||||
|
public static final int DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* float */
|
/* float */
|
||||||
@@ -221,6 +233,7 @@ public final class TermuxPropertyConstants {
|
|||||||
|
|
||||||
/* int */
|
/* int */
|
||||||
KEY_BELL_BEHAVIOUR,
|
KEY_BELL_BEHAVIOUR,
|
||||||
|
KEY_TERMINAL_CURSOR_BLINK_RATE,
|
||||||
|
|
||||||
/* float */
|
/* float */
|
||||||
KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR,
|
KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR,
|
||||||
|
@@ -188,6 +188,8 @@ public class TermuxSharedProperties implements SharedPropertiesParser {
|
|||||||
/* int */
|
/* int */
|
||||||
case TermuxPropertyConstants.KEY_BELL_BEHAVIOUR:
|
case TermuxPropertyConstants.KEY_BELL_BEHAVIOUR:
|
||||||
return (int) getBellBehaviourInternalPropertyValueFromValue(value);
|
return (int) getBellBehaviourInternalPropertyValueFromValue(value);
|
||||||
|
case TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE:
|
||||||
|
return (int) getTerminalCursorBlinkRateInternalPropertyValueFromValue(value);
|
||||||
|
|
||||||
/* float */
|
/* float */
|
||||||
case TermuxPropertyConstants.KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR:
|
case TermuxPropertyConstants.KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR:
|
||||||
@@ -257,6 +259,35 @@ public class TermuxSharedProperties implements SharedPropertiesParser {
|
|||||||
return SharedProperties.getDefaultIfNull(TermuxPropertyConstants.MAP_BELL_BEHAVIOUR.get(SharedProperties.toLowerCase(value)), TermuxPropertyConstants.DEFAULT_IVALUE_BELL_BEHAVIOUR);
|
return SharedProperties.getDefaultIfNull(TermuxPropertyConstants.MAP_BELL_BEHAVIOUR.get(SharedProperties.toLowerCase(value)), TermuxPropertyConstants.DEFAULT_IVALUE_BELL_BEHAVIOUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the int for the value if its not null and is between
|
||||||
|
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and
|
||||||
|
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MAX},
|
||||||
|
* otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR}.
|
||||||
|
*
|
||||||
|
* @param value The {@link String} value to convert.
|
||||||
|
* @return Returns the internal value for value.
|
||||||
|
*/
|
||||||
|
public static float getTerminalCursorBlinkRateInternalPropertyValueFromValue(String value) {
|
||||||
|
return rangeTerminalCursorBlinkRateValue(DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value itself if it is between
|
||||||
|
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN} and
|
||||||
|
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX},
|
||||||
|
* otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE}.
|
||||||
|
*
|
||||||
|
* @param value The value to clamp.
|
||||||
|
* @return Returns the clamped value.
|
||||||
|
*/
|
||||||
|
public static int rangeTerminalCursorBlinkRateValue(int value) {
|
||||||
|
return (int) DataUtils.rangedOrDefault(value,
|
||||||
|
TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE,
|
||||||
|
TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN,
|
||||||
|
TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the int for the value if its not null and is between
|
* Returns the int for the value if its not null and is between
|
||||||
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and
|
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and
|
||||||
@@ -418,6 +449,10 @@ public class TermuxSharedProperties implements SharedPropertiesParser {
|
|||||||
return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_BELL_BEHAVIOUR, true);
|
return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_BELL_BEHAVIOUR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getTerminalCursorBlinkRate() {
|
||||||
|
return rangeTerminalCursorBlinkRateValue((int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE, true));
|
||||||
|
}
|
||||||
|
|
||||||
public float getTerminalToolbarHeightScaleFactor() {
|
public float getTerminalToolbarHeightScaleFactor() {
|
||||||
return rangeTerminalToolbarHeightScaleFactorValue((float) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR, true));
|
return rangeTerminalToolbarHeightScaleFactorValue((float) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR, true));
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,12 @@ public class TermuxTerminalSessionClientBase implements TerminalSessionClient {
|
|||||||
public void onColorsChanged(TerminalSession changedSession) {
|
public void onColorsChanged(TerminalSession changedSession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTerminalCursorStateChange(boolean state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logError(String tag, String message) {
|
public void logError(String tag, String message) {
|
||||||
Logger.logError(tag, message);
|
Logger.logError(tag, message);
|
||||||
|
Reference in New Issue
Block a user