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

Added: Terminal CSI reporting of window and cell pixel size #4172

Merged
merged 1 commit into from
Sep 26, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ public final class TerminalEmulator {
/** The number of character rows and columns in the terminal screen. */
public int mRows, mColumns;

/** Size of a terminal cell in pixels. */
private int mCellWidthPixels, mCellHeightPixels;

/** The number of terminal transcript rows that can be scrolled back to. */
public static final int TERMINAL_TRANSCRIPT_ROWS_MIN = 100;
public static final int TERMINAL_TRANSCRIPT_ROWS_MAX = 50000;
Expand Down Expand Up @@ -314,13 +317,15 @@ static int mapDecSetBitToInternalBit(int decsetBit) {
}
}

public TerminalEmulator(TerminalOutput session, int columns, int rows, Integer transcriptRows, TerminalSessionClient client) {
public TerminalEmulator(TerminalOutput session, int columns, int rows, int cellWidthPixels, int cellHeightPixels, Integer transcriptRows, TerminalSessionClient client) {
mSession = session;
mScreen = mMainBuffer = new TerminalBuffer(columns, getTerminalTranscriptRows(transcriptRows), rows);
mAltBuffer = new TerminalBuffer(columns, rows, rows);
mClient = client;
mRows = rows;
mColumns = columns;
mCellWidthPixels = cellWidthPixels;
mCellHeightPixels = cellHeightPixels;
mTabStop = new boolean[mColumns];
reset();
}
Expand Down Expand Up @@ -370,7 +375,10 @@ public void sendMouseEvent(int mouseButton, int column, int row, boolean pressed
}
}

public void resize(int columns, int rows) {
public void resize(int columns, int rows, int cellWidthPixels, int cellHeightPixels) {
this.mCellWidthPixels = cellWidthPixels;
this.mCellHeightPixels = cellHeightPixels;

if (mRows == rows && mColumns == columns) {
return;
} else if (columns < 2 || rows < 2) {
Expand Down Expand Up @@ -1748,8 +1756,10 @@ private void doCsi(int b) {
mSession.write("\033[3;0;0t");
break;
case 14: // Report xterm window in pixels. Result is CSI 4 ; height ; width t
// We just report characters time 12 here.
mSession.write(String.format(Locale.US, "\033[4;%d;%dt", mRows * 12, mColumns * 12));
mSession.write(String.format(Locale.US, "\033[4;%d;%dt", mRows * mCellHeightPixels, mColumns * mCellWidthPixels));
break;
case 16: // Report xterm character cell size in pixels. Result is CSI 6 ; height ; width t
mSession.write(String.format(Locale.US, "\033[6;%d;%dt", mCellHeightPixels, mCellWidthPixels));
break;
case 18: // Report the size of the text area in characters. Result is CSI 8 ; height ; width t
mSession.write(String.format(Locale.US, "\033[8;%d;%dt", mRows, mColumns));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ public void updateTerminalSessionClient(TerminalSessionClient client) {
}

/** Inform the attached pty of the new size and reflow or initialize the emulator. */
public void updateSize(int columns, int rows, int fontWidth, int fontHeight) {
public void updateSize(int columns, int rows, int cellWidthPixels, int cellHeightPixels) {
if (mEmulator == null) {
initializeEmulator(columns, rows, fontWidth, fontHeight);
initializeEmulator(columns, rows, cellWidthPixels, cellHeightPixels);
} else {
JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns, fontWidth, fontHeight);
mEmulator.resize(columns, rows);
JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns, cellWidthPixels, cellHeightPixels);
mEmulator.resize(columns, rows, cellWidthPixels, cellHeightPixels);
}
}

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

int[] processId = new int[1];
mTerminalFileDescriptor = JNI.createSubprocess(mShellPath, mCwd, mArgs, mEnv, processId, rows, columns, cellWidth, cellHeight);
mTerminalFileDescriptor = JNI.createSubprocess(mShellPath, mCwd, mArgs, mEnv, processId, rows, columns, cellWidthPixels, cellHeightPixels);
mShellPid = processId[0];
mClient.setTerminalShellPid(this, mShellPid);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,24 @@ public void testCsi3J() {
assertEquals("y\nz", mTerminal.getScreen().getTranscriptText());
}

public void testReportPixelSize() {
int columns = 3;
int rows = 3;
withTerminalSized(columns, rows);
int cellWidth = TerminalTest.INITIAL_CELL_WIDTH_PIXELS;
int cellHeight = TerminalTest.INITIAL_CELL_HEIGHT_PIXELS;
assertEnteringStringGivesResponse("\033[14t", "\033[4;" + (rows*cellHeight) + ";" + (columns*cellWidth) + "t");
assertEnteringStringGivesResponse("\033[16t", "\033[6;" + cellHeight + ";" + cellWidth + "t");
columns = 23;
rows = 33;
resize(columns, rows);
assertEnteringStringGivesResponse("\033[14t", "\033[4;" + (rows*cellHeight) + ";" + (columns*cellWidth) + "t");
assertEnteringStringGivesResponse("\033[16t", "\033[6;" + cellHeight + ";" + cellWidth + "t");
cellWidth = 8;
cellHeight = 18;
mTerminal.resize(columns, rows, cellWidth, cellHeight);
assertEnteringStringGivesResponse("\033[14t", "\033[4;" + (rows*cellHeight) + ";" + (columns*cellWidth) + "t");
assertEnteringStringGivesResponse("\033[16t", "\033[6;" + cellHeight + ";" + cellWidth + "t");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ public void testHistory() {
assertLinesAre("777", "888", "999");
assertHistoryStartsWith("666", "555");

mTerminal.resize(cols, 2);
resize(cols, 2);
assertHistoryStartsWith("777", "666", "555");

mTerminal.resize(cols, 3);
resize(cols, 3);
assertHistoryStartsWith("666", "555");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ public void testResizeAfterHistoryWraparound() {
enterString("\r\n");
}
assertLinesAre("998 ", "999 ", " ");
mTerminal.resize(cols, 2);
resize(cols, 2);
assertLinesAre("999 ", " ");
mTerminal.resize(cols, 5);
resize(cols, 5);
assertLinesAre("996 ", "997 ", "998 ", "999 ", " ");
mTerminal.resize(cols, rows);
resize(cols, rows);
assertLinesAre("998 ", "999 ", " ");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void testReportTerminalSize() throws Exception {
assertEnteringStringGivesResponse("\033[18t", "\033[8;5;5t");
for (int width = 3; width < 12; width++) {
for (int height = 3; height < 12; height++) {
mTerminal.resize(width, height);
resize(width, height);
assertEnteringStringGivesResponse("\033[18t", "\033[8;" + height + ";" + width + "t");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@

public abstract class TerminalTestCase extends TestCase {

public static class MockTerminalOutput extends TerminalOutput {
public static final int INITIAL_CELL_WIDTH_PIXELS = 13;
public static final int INITIAL_CELL_HEIGHT_PIXELS = 15;

public static class MockTerminalOutput extends TerminalOutput {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
public final List<ChangedTitle> titleChanges = new ArrayList<>();
public final List<String> clipboardPuts = new ArrayList<>();
Expand Down Expand Up @@ -108,7 +111,7 @@ protected void setUp() throws Exception {

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

Expand Down Expand Up @@ -201,7 +204,7 @@ public TerminalTestCase assertLinesAre(String... lines) {
}

public TerminalTestCase resize(int cols, int rows) {
mTerminal.resize(cols, rows);
mTerminal.resize(cols, rows, INITIAL_CELL_WIDTH_PIXELS, INITIAL_CELL_HEIGHT_PIXELS);
assertInvariants();
return this;
}
Expand Down
Loading