SD sequence (`${CSI}${N}T`) was scrolling the whole width
of the terminal instead of just between the margins.
RI sequence (`${ESC}M`, move cursor up 1 line) was doing the same.
Fixed that.
Fixes#2576 where in tmux scrolling one of several
side-by-side panels down resulted in all visually scrolling.
Implement the following CSI escape sequences from
https://invisible-island.net/xterm/ctlseqs/ctlseqs.html:
> CSI Ps ; Ps ; Ps t
> [..]
> Ps = 1 4 ⇒ Report xterm text area size in pixels.
> Result is CSI 4 ; height ; width t
> [..]
> Ps = 1 6 ⇒ Report xterm character cell size in pixels.
> Result is CSI 6 ; height ; width t
Extracted from changes in https://github.com/termux/termux-app/pull/2973
by @MatanZ and adopted to play well with the just merged #3098 (.ws_xpixel
and .ws_ypixel values in winsize).
This allows to get terminal size in pixel using `TIOCGWINSZ` ioctl.
Set `.ws_xpixel` using `columns * cell_width` and set `.ws_ypixel` using `rows * cell_height`.
Cell width and height is font width and line spacing, respectively.
- The AutoFill type and hints are no longer hardcoded in `TerminalView` class and `TermuxActivity` layout xml. They are dynamically set to required values before making a manual AutoFill request and reverted back afterwards to default values. The hardcoded value `AUTOFILL_TYPE_TEXT` returned by `getAutofillType()` was causing the AutoFill UI to show on Activity starts, this will return `AUTOFILL_TYPE_NONE` by default now so that AutoFill UI isn't shown automatically.
- The AutoFill importance is no longer hardcoded in `TermuxActivity` layout xml and is returned by `TerminalView` class itself by `getImportantForAutofill()`.
- The AutoFill function in `TermuxActivity` for making a manual AutoFill request is moved to `TerminalView` class. This and moving of hardcoded values to `TerminalView` class mentioned above is done as complete logic of AutoFill should be handled by `TerminalView` class itself and not scattered in various places.
- The Terminal context menu now supports AutoFilling a username. Note that GBoard/Google Password Manager seems to have a bug where it will still show `Pick a saved password` instead of username, even though `AUTOFILL_HINT_USERNAME` is being requested, however it will still AutoFill a username of selected entry correctly.
- Pressing the back button to close the keyboard will also cancel the current manually requested AutoFill request and UI will not show when keyboard is opened again.
Closes#3909
The `copyTextToClipboard()` method has been updated to pass clip label when copying text to clipboard and `getTextFromClipboard()` and `getTextStringFromClipboardIfSet()` methods have been added to get current clipboard.
In other terminals, such as gnome-terminal, Shift-PgUp and Shift-PgDn
scroll the screen by a full page, rather than a single line. Adjust
termux to match.
This will work for both `SHIFT` extra key and hardware keyboards. The `SHIFT` extra key can be long held to lock it in an enabled state and `PGUP` and `PGDN` keys can be long held to repeat scrolling.
Closes#867
Currently the Termux terminal emulator prints "HI" in red with:
```sh
printf "\e[31;m HI \e[0m"
```
This is not how other terminals (tested on xterm, gnome-terminal,
alacritty and the mac built in terminal) handle it, since they parse
""\e[31;m" as "\e[31;0m", where the "0" resets the colors.
This change aligns with other terminals, as well as improves performance
by avoiding allocating a new int[] array for each byte processed by
`parseArg()`, and most importantly simplifies things by removing the
`mIsCSIStart` and `mLastCSIArg` state, preparing for supporting ':'
separated sub parameters such as used in
https://sw.kovidgoyal.net/kitty/underlines/
The `versionCode` has been bumped to `1000` so that users who have installed from F-Droid or GitHub should not have the app attempted to be updated by Google PlayStore and failing and also shown in PlayStore app updates list due to non-collaborative `v0.120` app release on PlayStore that set the `versionCode` higher than the latest F-Droid or GitHub `118` release. Unlike F-Droid, PlayStore does not check for difference in app APK signature before attempting to download and then failing to install due to signature mismatch.
- https://github.com/termux/termux-app/discussions/4000
- https://github.com/termux/termux-app/issues/4012
The exception below causing app crash happens because of malicious input where combining characters keep getting added to same column of the row and this increases the size of `mSpaceUsed` and `mText`, eventually causing a buffer overflow of `mSpaceUsed`, which is limited to max `32767` value as per java `short` limit, but the limit itself isn't the issue, but an endless number of combining characters being added. Check `MAX_COMBINING_CHARACTERS_PER_COLUMN` field javadocs for why the limit `15` was chosen.
```
curl -o matroska.js https://kimapr.net/lappy/matroska.js
cat matroska.js
```
The `charCount` below refers to value of `Character.charCount(codePoint)`, like before `oldCharactersUsedForColumn` is appended to `newCharactersUsedForColumn`.
```
TerminalRow: codePoint=112, mColumns=98, mText=637, columnToSet=18, mSpaceUsed=590, javaCharDifference=0, oldStartOfColumnIndex=510, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=1, oldNextColumnIndex=511, newNextColumnIndex=511, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=1
TerminalRow: codePoint=40, mColumns=98, mText=637, columnToSet=19, mSpaceUsed=590, javaCharDifference=0, oldStartOfColumnIndex=511, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=1, oldNextColumnIndex=512, newNextColumnIndex=512, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=1
TerminalRow: codePoint=40, mColumns=98, mText=637, columnToSet=20, mSpaceUsed=590, javaCharDifference=0, oldStartOfColumnIndex=512, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=1, oldNextColumnIndex=513, newNextColumnIndex=513, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=1
TerminalRow: codePoint=101, mColumns=98, mText=637, columnToSet=21, mSpaceUsed=590, javaCharDifference=0, oldStartOfColumnIndex=513, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=1, oldNextColumnIndex=514, newNextColumnIndex=514, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=1
TerminalRow: codePoint=917772, mColumns=98, mText=147, columnToSet=18, mSpaceUsed=98, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=3, oldNextColumnIndex=19, newNextColumnIndex=21, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
I TerminalRow: codePoint=65024, mColumns=98, mText=147, columnToSet=18, mSpaceUsed=100, javaCharDifference=1, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=3, newCharactersUsedForColumn=4, oldNextColumnIndex=21, newNextColumnIndex=22, charCount=1, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
TerminalRow: codePoint=917772, mColumns=98, mText=147, columnToSet=18, mSpaceUsed=101, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=4, newCharactersUsedForColumn=6, oldNextColumnIndex=22, newNextColumnIndex=24, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
...
TerminalRow: codePoint=917959, mColumns=98, mText=32781, columnToSet=18, mSpaceUsed=32763, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=32666, newCharactersUsedForColumn=32668, oldNextColumnIndex=32684, newNextColumnIndex=32686, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
TerminalRow: codePoint=917939, mColumns=98, mText=32781, columnToSet=18, mSpaceUsed=32765, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=32668, newCharactersUsedForColumn=32670, oldNextColumnIndex=32686, newNextColumnIndex=32688, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
TerminalRow: codePoint=917961, mColumns=98, mText=32781, columnToSet=18, mSpaceUsed=32767, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=32670, newCharactersUsedForColumn=32672, oldNextColumnIndex=32688, newNextColumnIndex=32690, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
TerminalRow: codePoint=917804, mColumns=98, mText=32781, columnToSet=18, mSpaceUsed=-32767, javaCharDifference=2, oldStartOfColumnIndex=18, oldCharactersUsedForColumn=1, newCharactersUsedForColumn=3, oldNextColumnIndex=19, newNextColumnIndex=21, charCount=2, oldCodePointDisplayWidth=1, newCodePointDisplayWidth=0
```
```
java.lang.ArrayIndexOutOfBoundsException: src.length=32781 srcPos=19 dst.length=32781 dstPos=21 length=-32786
at java.lang.System.arraycopy(System.java:469)
at com.termux.terminal.TerminalRow.setChar(TerminalRow.java:196)
at com.termux.terminal.TerminalBuffer.setChar(TerminalBuffer.java:455)
at com.termux.terminal.TerminalEmulator.emitCodePoint(TerminalEmulator.java:2380)
at com.termux.terminal.TerminalEmulator.processCodePoint(TerminalEmulator.java:624)
at com.termux.terminal.TerminalEmulator.processByte(TerminalEmulator.java:520)
at com.termux.terminal.TerminalEmulator.append(TerminalEmulator.java:487)
at com.termux.terminal.TerminalSession$MainThreadHandler.handleMessage(TerminalSession.java:358)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7664)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
```
See also following links for history of related changes to `TerminalRow` for combining characters. Note that jackpal terminal does not crash for above, which termux-app is based on, but changes were done by fornwall in initial commit of termux-app to change the behaviour, hence the crash, but he added the `FIXME: Put a limit of combining characters` comment as a note to solve the current issue in future, which is now.
- 9a47042620
- https://github.com/jackpal/Android-Terminal-Emulator/pull/338
- a18ee58f7a (diff-f84d215b18106c037e01986a3968fa54b74691174a78fcc99493f745d3805be5)Closes#3839
java.lang.ArrayIndexOutOfBoundsException: length=64; index=-1
at com.termux.terminal.TerminalRow.setChar(TerminalRow.java:127)
at com.termux.terminal.TerminalBuffer.setChar(TerminalBuffer.java:413)
at com.termux.terminal.TerminalEmulator.emitCodePoint(TerminalEmulator.java:2329)
at com.termux.terminal.TerminalEmulator.processCodePoint(TerminalEmulator.java:617)
at com.termux.terminal.TerminalEmulator.processByte(TerminalEmulator.java:513)
at com.termux.terminal.TerminalEmulator.append(TerminalEmulator.java:480)
at com.termux.terminal.TerminalSession$MainThreadHandler.handleMessage(TerminalSession.java:339)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8349)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
java.lang.NumberFormatException: For input string: " a"
at java.lang.Long.parseLong(Long.java:583)
at java.lang.Long.valueOf(Long.java:781)
at java.lang.Long.decode(Long.java:933)
at com.termux.terminal.TerminalEmulator.doDeviceControl(TerminalEmulator.java:940)
at com.termux.terminal.TerminalEmulator.processCodePoint(TerminalEmulator.java:813)
Firstly, `TerminalBuffer.blockSet()` was throwing the exception since `sx + w > mColumns` which was technically passed by TerminalEmulator.blockClear()`. Actual value would be `mCursorRow + columnsToMove + columnsToDelete > mColumns`.
Secondly, the call to `blockClear()` should not be needed since it the `blockCopy()` would overwrite the columns to be deleted on copy.
Run `printf "\e['~"` to delete 1 column and `printf "\e[3'~"` to delete 3 columns. Run `printf "\e[3'}"` to insert 2 columns.
java.lang.IllegalArgumentException: Illegal arguments! blockSet(78, 0, 1, 30, 32, 56, 30)
at com.termux.terminal.TerminalBuffer.blockSet(TerminalBuffer.java:397)
at com.termux.terminal.TerminalEmulator.blockClear(TerminalEmulator.java:2035)
at com.termux.terminal.TerminalEmulator.processCodePoint(TerminalEmulator.java:799)
java.lang.ArrayIndexOutOfBoundsException: src.length=132 srcPos=90 dst.length=16 dstPos=0 length=-2
at java.lang.System.arraycopy(System.java:469)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:597)
at java.lang.StringBuilder.append(StringBuilder.java:191)
at com.termux.terminal.TerminalBuffer.getSelectedText(TerminalBuffer.java:97)
at com.termux.terminal.TerminalBuffer.getSelectedText(TerminalBuffer.java:57)
at com.termux.terminal.TerminalBuffer.getSelectedText(TerminalBuffer.java:53)
at com.termux.terminal.TerminalEmulator.getSelectedText(TerminalEmulator.java:2401)
at com.termux.view.textselection.TextSelectionCursorController$1.onActionItemClicked(TextSelectionCursorController.java:140)