Skip to content

Commit 254e885

Browse files
fornwallagnostic-apollo
authored andcommitted
Added: Terminal CSI reporting of window and cell pixel size
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 #2973 by @MatanZ and adopted to play well with the just merged #3098 (.ws_xpixel and .ws_ypixel values in winsize).
1 parent ee9b31a commit 254e885

File tree

7 files changed

+53
-20
lines changed

7 files changed

+53
-20
lines changed

terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java

+14-4
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ public final class TerminalEmulator {
136136
/** The number of character rows and columns in the terminal screen. */
137137
public int mRows, mColumns;
138138

139+
/** Size of a terminal cell in pixels. */
140+
private int mCellWidthPixels, mCellHeightPixels;
141+
139142
/** The number of terminal transcript rows that can be scrolled back to. */
140143
public static final int TERMINAL_TRANSCRIPT_ROWS_MIN = 100;
141144
public static final int TERMINAL_TRANSCRIPT_ROWS_MAX = 50000;
@@ -311,13 +314,15 @@ static int mapDecSetBitToInternalBit(int decsetBit) {
311314
}
312315
}
313316

314-
public TerminalEmulator(TerminalOutput session, int columns, int rows, Integer transcriptRows, TerminalSessionClient client) {
317+
public TerminalEmulator(TerminalOutput session, int columns, int rows, int cellWidthPixels, int cellHeightPixels, Integer transcriptRows, TerminalSessionClient client) {
315318
mSession = session;
316319
mScreen = mMainBuffer = new TerminalBuffer(columns, getTerminalTranscriptRows(transcriptRows), rows);
317320
mAltBuffer = new TerminalBuffer(columns, rows, rows);
318321
mClient = client;
319322
mRows = rows;
320323
mColumns = columns;
324+
mCellWidthPixels = cellWidthPixels;
325+
mCellHeightPixels = cellHeightPixels;
321326
mTabStop = new boolean[mColumns];
322327
reset();
323328
}
@@ -367,7 +372,10 @@ public void sendMouseEvent(int mouseButton, int column, int row, boolean pressed
367372
}
368373
}
369374

370-
public void resize(int columns, int rows) {
375+
public void resize(int columns, int rows, int cellWidthPixels, int cellHeightPixels) {
376+
this.mCellWidthPixels = cellWidthPixels;
377+
this.mCellHeightPixels = cellHeightPixels;
378+
371379
if (mRows == rows && mColumns == columns) {
372380
return;
373381
} else if (columns < 2 || rows < 2) {
@@ -1745,8 +1753,10 @@ private void doCsi(int b) {
17451753
mSession.write("\033[3;0;0t");
17461754
break;
17471755
case 14: // Report xterm window in pixels. Result is CSI 4 ; height ; width t
1748-
// We just report characters time 12 here.
1749-
mSession.write(String.format(Locale.US, "\033[4;%d;%dt", mRows * 12, mColumns * 12));
1756+
mSession.write(String.format(Locale.US, "\033[4;%d;%dt", mRows * mCellHeightPixels, mColumns * mCellWidthPixels));
1757+
break;
1758+
case 16: // Report xterm character cell size in pixels. Result is CSI 6 ; height ; width t
1759+
mSession.write(String.format(Locale.US, "\033[6;%d;%dt", mCellHeightPixels, mCellWidthPixels));
17501760
break;
17511761
case 18: // Report the size of the text area in characters. Result is CSI 8 ; height ; width t
17521762
mSession.write(String.format(Locale.US, "\033[8;%d;%dt", mRows, mColumns));

terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ public void updateTerminalSessionClient(TerminalSessionClient client) {
100100
}
101101

102102
/** Inform the attached pty of the new size and reflow or initialize the emulator. */
103-
public void updateSize(int columns, int rows, int fontWidth, int fontHeight) {
103+
public void updateSize(int columns, int rows, int cellWidthPixels, int cellHeightPixels) {
104104
if (mEmulator == null) {
105-
initializeEmulator(columns, rows, fontWidth, fontHeight);
105+
initializeEmulator(columns, rows, cellWidthPixels, cellHeightPixels);
106106
} else {
107-
JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns, fontWidth, fontHeight);
108-
mEmulator.resize(columns, rows);
107+
JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns, cellWidthPixels, cellHeightPixels);
108+
mEmulator.resize(columns, rows, cellWidthPixels, cellHeightPixels);
109109
}
110110
}
111111

@@ -120,11 +120,11 @@ public String getTitle() {
120120
* @param columns The number of columns in the terminal window.
121121
* @param rows The number of rows in the terminal window.
122122
*/
123-
public void initializeEmulator(int columns, int rows, int cellWidth, int cellHeight) {
124-
mEmulator = new TerminalEmulator(this, columns, rows, mTranscriptRows, mClient);
123+
public void initializeEmulator(int columns, int rows, int cellWidthPixels, int cellHeightPixels) {
124+
mEmulator = new TerminalEmulator(this, columns, rows, cellWidthPixels, cellHeightPixels, mTranscriptRows, mClient);
125125

126126
int[] processId = new int[1];
127-
mTerminalFileDescriptor = JNI.createSubprocess(mShellPath, mCwd, mArgs, mEnv, processId, rows, columns, cellWidth, cellHeight);
127+
mTerminalFileDescriptor = JNI.createSubprocess(mShellPath, mCwd, mArgs, mEnv, processId, rows, columns, cellWidthPixels, cellHeightPixels);
128128
mShellPid = processId[0];
129129

130130
final FileDescriptor terminalFileDescriptorWrapped = wrapFileDescriptor(mTerminalFileDescriptor, mClient);

terminal-emulator/src/test/java/com/termux/terminal/ControlSequenceIntroducerTest.java

+20
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,24 @@ public void testCsi3J() {
6262
assertEquals("y\nz", mTerminal.getScreen().getTranscriptText());
6363
}
6464

65+
public void testReportPixelSize() {
66+
int columns = 3;
67+
int rows = 3;
68+
withTerminalSized(columns, rows);
69+
int cellWidth = TerminalTest.INITIAL_CELL_WIDTH_PIXELS;
70+
int cellHeight = TerminalTest.INITIAL_CELL_HEIGHT_PIXELS;
71+
assertEnteringStringGivesResponse("\033[14t", "\033[4;" + (rows*cellHeight) + ";" + (columns*cellWidth) + "t");
72+
assertEnteringStringGivesResponse("\033[16t", "\033[6;" + cellHeight + ";" + cellWidth + "t");
73+
columns = 23;
74+
rows = 33;
75+
resize(columns, rows);
76+
assertEnteringStringGivesResponse("\033[14t", "\033[4;" + (rows*cellHeight) + ";" + (columns*cellWidth) + "t");
77+
assertEnteringStringGivesResponse("\033[16t", "\033[6;" + cellHeight + ";" + cellWidth + "t");
78+
cellWidth = 8;
79+
cellHeight = 18;
80+
mTerminal.resize(columns, rows, cellWidth, cellHeight);
81+
assertEnteringStringGivesResponse("\033[14t", "\033[4;" + (rows*cellHeight) + ";" + (columns*cellWidth) + "t");
82+
assertEnteringStringGivesResponse("\033[16t", "\033[6;" + cellHeight + ";" + cellWidth + "t");
83+
}
84+
6585
}

terminal-emulator/src/test/java/com/termux/terminal/HistoryTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ public void testHistory() {
1111
assertLinesAre("777", "888", "999");
1212
assertHistoryStartsWith("666", "555");
1313

14-
mTerminal.resize(cols, 2);
14+
resize(cols, 2);
1515
assertHistoryStartsWith("777", "666", "555");
1616

17-
mTerminal.resize(cols, 3);
17+
resize(cols, 3);
1818
assertHistoryStartsWith("666", "555");
1919
}
2020

terminal-emulator/src/test/java/com/termux/terminal/ResizeTest.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ public void testResizeAfterHistoryWraparound() {
7272
enterString("\r\n");
7373
}
7474
assertLinesAre("998 ", "999 ", " ");
75-
mTerminal.resize(cols, 2);
75+
resize(cols, 2);
7676
assertLinesAre("999 ", " ");
77-
mTerminal.resize(cols, 5);
77+
resize(cols, 5);
7878
assertLinesAre("996 ", "997 ", "998 ", "999 ", " ");
79-
mTerminal.resize(cols, rows);
79+
resize(cols, rows);
8080
assertLinesAre("998 ", "999 ", " ");
8181
}
8282

terminal-emulator/src/test/java/com/termux/terminal/TerminalTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public void testReportTerminalSize() throws Exception {
8282
assertEnteringStringGivesResponse("\033[18t", "\033[8;5;5t");
8383
for (int width = 3; width < 12; width++) {
8484
for (int height = 3; height < 12; height++) {
85-
mTerminal.resize(width, height);
85+
resize(width, height);
8686
assertEnteringStringGivesResponse("\033[18t", "\033[8;" + height + ";" + width + "t");
8787
}
8888
}

terminal-emulator/src/test/java/com/termux/terminal/TerminalTestCase.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313

1414
public abstract class TerminalTestCase extends TestCase {
1515

16-
public static class MockTerminalOutput extends TerminalOutput {
16+
public static final int INITIAL_CELL_WIDTH_PIXELS = 13;
17+
public static final int INITIAL_CELL_HEIGHT_PIXELS = 15;
18+
19+
public static class MockTerminalOutput extends TerminalOutput {
1720
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
1821
public final List<ChangedTitle> titleChanges = new ArrayList<>();
1922
public final List<String> clipboardPuts = new ArrayList<>();
@@ -108,7 +111,7 @@ protected void setUp() throws Exception {
108111

109112
protected TerminalTestCase withTerminalSized(int columns, int rows) {
110113
// The tests aren't currently using the client, so a null client will suffice, a dummy client should be implemented if needed
111-
mTerminal = new TerminalEmulator(mOutput, columns, rows, rows * 2, null);
114+
mTerminal = new TerminalEmulator(mOutput, columns, rows, INITIAL_CELL_WIDTH_PIXELS, INITIAL_CELL_HEIGHT_PIXELS, rows * 2, null);
112115
return this;
113116
}
114117

@@ -201,7 +204,7 @@ public TerminalTestCase assertLinesAre(String... lines) {
201204
}
202205

203206
public TerminalTestCase resize(int cols, int rows) {
204-
mTerminal.resize(cols, rows);
207+
mTerminal.resize(cols, rows, INITIAL_CELL_WIDTH_PIXELS, INITIAL_CELL_HEIGHT_PIXELS);
205208
assertInvariants();
206209
return this;
207210
}

0 commit comments

Comments
 (0)