mirror of
https://gitlab.com/AutumnMeowMeow/jexer
synced 2024-09-19 11:50:19 -06:00
Support TTerminalWindow resizing via ptypipe
This commit is contained in:
parent
be72cb5ccb
commit
1d99a38f2b
4 changed files with 88 additions and 15 deletions
26
README.md
26
README.md
|
@ -196,6 +196,14 @@ The following properties control features of Jexer:
|
|||
be faster on slower systems but also more likely to have screen
|
||||
tearing. Default: true.
|
||||
|
||||
jexer.TTerminal.ptypipe
|
||||
-----------------------
|
||||
|
||||
Used by jexer.TTerminalWindow. If true, spawn shell using the
|
||||
'ptypipe' utility rather than 'script'. This permits terminals to
|
||||
resize with the window. ptypipe is a separate C language utility,
|
||||
available at https://github.com/klamonte/ptypipe. Default: false.
|
||||
|
||||
|
||||
|
||||
Known Issues / Arbitrary Decisions
|
||||
|
@ -213,19 +221,19 @@ ambiguous. This section describes such issues.
|
|||
input (see the ENABLE_LINE_INPUT flag for GetConsoleMode() and
|
||||
SetConsoleMode()).
|
||||
|
||||
- TTerminalWindow launches 'script -fqe /dev/null' or 'script -q -F
|
||||
/dev/null' on non-Windows platforms. This is a workaround for the
|
||||
C library behavior of checking for a tty: script launches $SHELL
|
||||
in a pseudo-tty. This works on Linux and Mac but might not on
|
||||
other Posix-y platforms.
|
||||
- TTerminalWindow by default launches 'script -fqe /dev/null' or
|
||||
'script -q -F /dev/null' on non-Windows platforms. This is a
|
||||
workaround for the C library behavior of checking for a tty:
|
||||
script launches $SHELL in a pseudo-tty. This works on Linux and
|
||||
Mac but might not on other Posix-y platforms.
|
||||
|
||||
- Closing a TTerminalWindow without exiting the process inside it
|
||||
may result in a zombie 'script' process.
|
||||
|
||||
- TTerminalWindow cannot notify the child process of changes in
|
||||
window size, due to Java's lack of support for forkpty() and
|
||||
similar. Solving this requires C, and will be pursued only if
|
||||
sufficient user requests come in.
|
||||
- TTerminalWindow can only notify the child process of changes in
|
||||
window size if using the 'ptypipe' utility, due to Java's lack of
|
||||
support for forkpty() and similar. ptypipe is available at
|
||||
https://github.com/klamonte/ptypipe.
|
||||
|
||||
- Java's InputStreamReader as used by the ECMA48 backend requires a
|
||||
valid UTF-8 stream. The default X10 encoding for mouse
|
||||
|
|
|
@ -80,10 +80,6 @@ Roadmap
|
|||
1.1.0 Wishlist
|
||||
--------------
|
||||
|
||||
- TTerminal
|
||||
- Handle resize events (pass to child process). Will need to switch
|
||||
to forkpty(), or ship a C wrapper process.
|
||||
|
||||
- Screen
|
||||
- Allow complex characters in putCharXY() and detect them in putStringXY().
|
||||
|
||||
|
|
|
@ -60,6 +60,13 @@ public class TTerminalWindow extends TScrollableWindow
|
|||
*/
|
||||
private Process shell;
|
||||
|
||||
/**
|
||||
* If true, we are using the ptypipe utility to support dynamic window
|
||||
* resizing. ptypipe is available at
|
||||
* https://github.com/klamonte/ptypipe .
|
||||
*/
|
||||
private boolean ptypipe = false;
|
||||
|
||||
/**
|
||||
* Claim the keystrokes the emulator will need.
|
||||
*/
|
||||
|
@ -165,10 +172,19 @@ public class TTerminalWindow extends TScrollableWindow
|
|||
String [] cmdShellBSD = {
|
||||
"script", "-q", "-F", "/dev/null"
|
||||
};
|
||||
String [] cmdShellPtypipe = {
|
||||
"ptypipe", "/bin/bash", "--login"
|
||||
};
|
||||
// Spawn a shell and pass its I/O to the other constructor.
|
||||
|
||||
ProcessBuilder pb;
|
||||
if (System.getProperty("os.name").startsWith("Windows")) {
|
||||
if ((System.getProperty("jexer.TTerminal.ptypipe") != null)
|
||||
&& (System.getProperty("jexer.TTerminal.ptypipe").
|
||||
equals("true"))
|
||||
) {
|
||||
pb = new ProcessBuilder(cmdShellPtypipe);
|
||||
ptypipe = true;
|
||||
} else if (System.getProperty("os.name").startsWith("Windows")) {
|
||||
pb = new ProcessBuilder(cmdShellWindows);
|
||||
} else if (System.getProperty("os.name").startsWith("Mac")) {
|
||||
pb = new ProcessBuilder(cmdShellBSD);
|
||||
|
@ -429,6 +445,14 @@ public class TTerminalWindow extends TScrollableWindow
|
|||
|
||||
// Get out of scrollback
|
||||
setVerticalValue(0);
|
||||
|
||||
if (ptypipe) {
|
||||
emulator.setWidth(getWidth() - 2);
|
||||
emulator.setHeight(getHeight() - 2);
|
||||
|
||||
emulator.writeRemote("\033[8;" + (getHeight() - 2) + ";" +
|
||||
(getWidth() - 2) + "t");
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ public class ECMA48 implements Runnable {
|
|||
*
|
||||
* @param str string to send
|
||||
*/
|
||||
private void writeRemote(final String str) {
|
||||
public void writeRemote(final String str) {
|
||||
if (stopReaderThread) {
|
||||
// Reader hit EOF, bail out now.
|
||||
close();
|
||||
|
@ -221,6 +221,7 @@ public class ECMA48 implements Runnable {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
outputStream.flush();
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
outputStream.write(str.charAt(i));
|
||||
}
|
||||
|
@ -235,6 +236,7 @@ public class ECMA48 implements Runnable {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
output.flush();
|
||||
output.write(str);
|
||||
output.flush();
|
||||
} catch (IOException e) {
|
||||
|
@ -538,6 +540,22 @@ public class ECMA48 implements Runnable {
|
|||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display width.
|
||||
*
|
||||
* @param width the new width
|
||||
*/
|
||||
public final void setWidth(final int width) {
|
||||
this.width = width;
|
||||
rightMargin = width - 1;
|
||||
if (currentState.cursorX >= width) {
|
||||
currentState.cursorX = width - 1;
|
||||
}
|
||||
if (savedState.cursorX >= width) {
|
||||
savedState.cursorX = width - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Physical display height. We start at 80x24, but the user can resize
|
||||
* us bigger/smaller.
|
||||
|
@ -553,6 +571,33 @@ public class ECMA48 implements Runnable {
|
|||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display height.
|
||||
*
|
||||
* @param height the new height
|
||||
*/
|
||||
public final void setHeight(final int height) {
|
||||
this.height = height;
|
||||
scrollRegionBottom = height - 1;
|
||||
if (scrollRegionTop >= scrollRegionBottom) {
|
||||
scrollRegionTop = 0;
|
||||
}
|
||||
if (currentState.cursorY >= height) {
|
||||
currentState.cursorY = height - 1;
|
||||
}
|
||||
if (savedState.cursorY >= height) {
|
||||
savedState.cursorY = height - 1;
|
||||
}
|
||||
while (display.size() < height) {
|
||||
DisplayLine line = new DisplayLine(currentState.attr);
|
||||
line.setReverseColor(reverseVideo);
|
||||
display.add(line);
|
||||
}
|
||||
while (display.size() > height) {
|
||||
scrollback.add(display.remove(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Top margin of the scrolling region.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue