Skip to content

Commit caa2d14

Browse files
committedMar 6, 2023
Fix restoration of Terminal at close, fixes #819
1 parent 0b97167 commit caa2d14

File tree

6 files changed

+52
-49
lines changed

6 files changed

+52
-49
lines changed
 

‎reader/src/test/java/org/jline/reader/impl/LineReaderTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,15 @@ private String computeGroupPost(List<Candidate> c, boolean autoGroup, boolean gr
102102
public void testConEmuLineReaderClearScreen() throws IOException {
103103
System.setProperty("org.jline.terminal.conemu.disable-activate", "false");
104104
StringWriter sw = new StringWriter();
105-
AbstractWindowsTerminal terminal = new AbstractWindowsTerminal(new BufferedWriter(sw), "name", TYPE_WINDOWS_CONEMU, Charset.defaultCharset(),
106-
false, Terminal.SignalHandler.SIG_DFL) {
105+
AbstractWindowsTerminal<?> terminal = new AbstractWindowsTerminal<Object>(new BufferedWriter(sw), "name", TYPE_WINDOWS_CONEMU, Charset.defaultCharset(),
106+
false, Terminal.SignalHandler.SIG_DFL, null, null) {
107107
@Override
108-
protected int getConsoleMode() {
108+
protected int getConsoleMode(Object console) {
109109
return 0;
110110
}
111111

112112
@Override
113-
protected void setConsoleMode(int mode) {
113+
protected void setConsoleMode(Object console, int mode) {
114114
}
115115

116116
@Override

‎reader/src/test/java/org/jline/terminal/impl/AbstractWindowsTerminalTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,21 @@ private void process(TestTerminal terminal, int c) {
7878
}
7979
}
8080

81-
private static class TestTerminal extends AbstractWindowsTerminal {
81+
private static class TestTerminal extends AbstractWindowsTerminal<Object> {
8282
public TestTerminal(StringWriter sw) throws IOException {
8383
super(new AnsiWriter(new BufferedWriter(sw)), "name",
8484
AbstractWindowsTerminal.TYPE_DUMB,
8585
Charset.defaultCharset(),
86-
false, SignalHandler.SIG_DFL);
86+
false, SignalHandler.SIG_DFL, null, null);
8787
}
8888

8989
@Override
90-
protected int getConsoleMode() {
90+
protected int getConsoleMode(Object console) {
9191
return 0;
9292
}
9393

9494
@Override
95-
protected void setConsoleMode(int mode) {
95+
protected void setConsoleMode(Object console, int mode) {
9696
}
9797

9898
@Override

‎terminal-jansi/src/main/java/org/jline/terminal/impl/jansi/win/JansiWinSysTerminal.java

+11-16
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import static org.fusesource.jansi.internal.Kernel32.WaitForSingleObject;
4040
import static org.fusesource.jansi.internal.Kernel32.readConsoleInputHelper;
4141

42-
public class JansiWinSysTerminal extends AbstractWindowsTerminal {
42+
public class JansiWinSysTerminal extends AbstractWindowsTerminal<Long> {
4343

4444
private static final long consoleIn = GetStdHandle(STD_INPUT_HANDLE);
4545
private static final long consoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -115,18 +115,13 @@ public static boolean isWindowsSystemStream(TerminalProvider.Stream stream) {
115115
return Kernel32.GetConsoleMode(console, mode) != 0;
116116
}
117117

118-
private long console;
119-
private long outputHandle;
120-
121118
JansiWinSysTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler,
122-
long console, long outputHandle) throws IOException {
123-
super(writer, name, type, encoding, nativeSignals, signalHandler);
124-
this.console = console;
125-
this.outputHandle = outputHandle;
119+
long inConsole, long outConsole) throws IOException {
120+
super(writer, name, type, encoding, nativeSignals, signalHandler, inConsole, outConsole);
126121
}
127122

128123
@Override
129-
protected int getConsoleMode() {
124+
protected int getConsoleMode(Long console) {
130125
int[] mode = new int[1];
131126
if (Kernel32.GetConsoleMode(console, mode) == 0) {
132127
return -1;
@@ -135,28 +130,28 @@ protected int getConsoleMode() {
135130
}
136131

137132
@Override
138-
protected void setConsoleMode(int mode) {
133+
protected void setConsoleMode(Long console, int mode) {
139134
Kernel32.SetConsoleMode(console, mode);
140135
}
141136

142137
public Size getSize() {
143138
CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO();
144-
Kernel32.GetConsoleScreenBufferInfo(outputHandle, info);
139+
Kernel32.GetConsoleScreenBufferInfo(outConsole, info);
145140
return new Size(info.windowWidth(), info.windowHeight());
146141
}
147142

148143
@Override
149144
public Size getBufferSize() {
150145
CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO();
151-
Kernel32.GetConsoleScreenBufferInfo(outputHandle, info);
146+
Kernel32.GetConsoleScreenBufferInfo(outConsole, info);
152147
return new Size(info.size.x, info.size.y);
153148
}
154149

155150
protected boolean processConsoleInput() throws IOException {
156151
INPUT_RECORD[] events;
157-
if (console != INVALID_HANDLE_VALUE
158-
&& WaitForSingleObject(console, 100) == 0) {
159-
events = readConsoleInputHelper(console, 1, false);
152+
if (inConsole != INVALID_HANDLE_VALUE
153+
&& WaitForSingleObject(inConsole, 100) == 0) {
154+
events = readConsoleInputHelper(inConsole, 1, false);
160155
} else {
161156
return false;
162157
}
@@ -228,7 +223,7 @@ private void processMouseEvent(Kernel32.MOUSE_EVENT_RECORD mouseEvent) throws IO
228223
@Override
229224
public Cursor getCursorPosition(IntConsumer discarded) {
230225
CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO();
231-
if (GetConsoleScreenBufferInfo(outputHandle, info) == 0) {
226+
if (GetConsoleScreenBufferInfo(outConsole, info) == 0) {
232227
throw new IOError(new IOException("Could not get the cursor position: " + getLastErrorMessage()));
233228
}
234229
return new Cursor(info.cursorPosition.x, info.cursorPosition.y);

‎terminal-jna/src/main/java/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java

+12-11
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
import org.jline.terminal.Size;
2222
import org.jline.terminal.impl.AbstractWindowsTerminal;
2323
import org.jline.terminal.spi.TerminalProvider;
24-
import org.jline.utils.InfoCmp;
24+
import org.jline.utils.InfoCmp.Capability;
2525
import org.jline.utils.OSUtils;
2626

27-
public class JnaWinSysTerminal extends AbstractWindowsTerminal {
27+
public class JnaWinSysTerminal extends AbstractWindowsTerminal<Pointer> {
2828

2929
private static final Pointer consoleIn = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_INPUT_HANDLE);
3030
private static final Pointer consoleOut = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_OUTPUT_HANDLE);
@@ -71,7 +71,7 @@ public static JnaWinSysTerminal createTerminal(String name, String type, boolean
7171
}
7272
}
7373
}
74-
JnaWinSysTerminal terminal = new JnaWinSysTerminal(writer, name, type, encoding, nativeSignals, signalHandler);
74+
JnaWinSysTerminal terminal = new JnaWinSysTerminal(writer, name, type, encoding, nativeSignals, signalHandler, JnaWinSysTerminal.consoleIn, console);
7575
// Start input pump thread
7676
if (!paused) {
7777
terminal.resume();
@@ -96,26 +96,27 @@ public static boolean isWindowsSystemStream(TerminalProvider.Stream stream) {
9696
}
9797
}
9898

99-
JnaWinSysTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler) throws IOException {
100-
super(writer, name, type, encoding, nativeSignals, signalHandler);
101-
strings.put(InfoCmp.Capability.key_mouse, "\\E[M");
99+
JnaWinSysTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler,
100+
Pointer inConsole, Pointer outConsole) throws IOException {
101+
super(writer, name, type, encoding, nativeSignals, signalHandler, inConsole, outConsole);
102+
this.strings.put(Capability.key_mouse, "\\E[M");
102103
}
103104

104105
@Override
105-
protected int getConsoleMode() {
106+
protected int getConsoleMode(Pointer console) {
106107
IntByReference mode = new IntByReference();
107-
Kernel32.INSTANCE.GetConsoleMode(consoleIn, mode);
108+
Kernel32.INSTANCE.GetConsoleMode(console, mode);
108109
return mode.getValue();
109110
}
110111

111112
@Override
112-
protected void setConsoleMode(int mode) {
113-
Kernel32.INSTANCE.SetConsoleMode(consoleIn, mode);
113+
protected void setConsoleMode(Pointer console, int mode) {
114+
Kernel32.INSTANCE.SetConsoleMode(console, mode);
114115
}
115116

116117
public Size getSize() {
117118
Kernel32.CONSOLE_SCREEN_BUFFER_INFO info = new Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
118-
Kernel32.INSTANCE.GetConsoleScreenBufferInfo(consoleOut, info);
119+
Kernel32.INSTANCE.GetConsoleScreenBufferInfo(outConsole, info);
119120
return new Size(info.windowWidth(), info.windowHeight());
120121
}
121122

‎terminal/src/main/java/org/jline/terminal/impl/AbstractWindowsTerminal.java

+17-10
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import java.io.PrintWriter;
2828
import java.io.Writer;
2929
import java.nio.charset.Charset;
30-
import java.nio.charset.StandardCharsets;
3130
import java.util.HashMap;
3231
import java.util.Map;
3332

@@ -43,7 +42,7 @@
4342
* the writer() becomes the primary output, while the output() is bridged
4443
* to the writer() using a WriterOutputStream wrapper.
4544
*/
46-
public abstract class AbstractWindowsTerminal extends AbstractTerminal {
45+
public abstract class AbstractWindowsTerminal<Console> extends AbstractTerminal {
4746

4847
public static final String TYPE_WINDOWS = "windows";
4948
public static final String TYPE_WINDOWS_256_COLOR = "windows-256color";
@@ -70,7 +69,10 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal {
7069
protected final Map<Signal, Object> nativeHandlers = new HashMap<>();
7170
protected final ShutdownHooks.Task closer;
7271
protected final Attributes attributes = new Attributes();
73-
protected final int originalConsoleMode;
72+
protected final Console inConsole;
73+
protected final Console outConsole;
74+
protected final int originalInConsoleMode;
75+
protected final int originalOutConsoleMode;
7476

7577
protected final Object lock = new Object();
7678
protected boolean paused = true;
@@ -80,17 +82,21 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal {
8082
protected boolean focusTracking = false;
8183
private volatile boolean closing;
8284

83-
public AbstractWindowsTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler) throws IOException {
85+
public AbstractWindowsTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler,
86+
Console inConsole, Console outConsole) throws IOException {
8487
super(name, type, encoding, signalHandler);
8588
NonBlockingPumpReader reader = NonBlocking.nonBlockingPumpReader();
8689
this.slaveInputPipe = reader.getWriter();
8790
this.reader = reader;
8891
this.input = NonBlocking.nonBlockingStream(reader, encoding());
8992
this.writer = new PrintWriter(writer);
9093
this.output = new WriterOutputStream(writer, encoding());
94+
this.inConsole = inConsole;
95+
this.outConsole = outConsole;
9196
parseInfoCmp();
9297
// Attributes
93-
originalConsoleMode = getConsoleMode();
98+
this.originalInConsoleMode = getConsoleMode(inConsole);
99+
this.originalOutConsoleMode = getConsoleMode(outConsole);
94100
attributes.setLocalFlag(Attributes.LocalFlag.ISIG, true);
95101
attributes.setControlChar(Attributes.ControlChar.VINTR, ctrl('C'));
96102
attributes.setControlChar(Attributes.ControlChar.VEOF, ctrl('D'));
@@ -147,7 +153,7 @@ public OutputStream output() {
147153
}
148154

149155
public Attributes getAttributes() {
150-
int mode = getConsoleMode();
156+
int mode = getConsoleMode(inConsole);
151157
if ((mode & ENABLE_ECHO_INPUT) != 0) {
152158
attributes.setLocalFlag(Attributes.LocalFlag.ECHO, true);
153159
}
@@ -173,7 +179,7 @@ protected void updateConsoleMode() {
173179
if (tracking != MouseTracking.Off) {
174180
mode |= ENABLE_MOUSE_INPUT;
175181
}
176-
setConsoleMode(mode);
182+
setConsoleMode(inConsole, mode);
177183
}
178184

179185
protected int ctrl(char key) {
@@ -196,7 +202,8 @@ protected void doClose() throws IOException {
196202
}
197203
reader.close();
198204
writer.close();
199-
setConsoleMode(originalConsoleMode);
205+
setConsoleMode(inConsole, originalInConsoleMode);
206+
setConsoleMode(outConsole, originalOutConsoleMode);
200207
}
201208

202209
static final int SHIFT_FLAG = 0x01;
@@ -487,9 +494,9 @@ public boolean trackMouse(MouseTracking tracking) {
487494
return true;
488495
}
489496

490-
protected abstract int getConsoleMode();
497+
protected abstract int getConsoleMode(Console console);
491498

492-
protected abstract void setConsoleMode(int mode);
499+
protected abstract void setConsoleMode(Console console, int mode);
493500

494501
/**
495502
* Read a single input event from the input buffer and process it.

‎terminal/src/test/java/org/jline/terminal/impl/AbstractWindowsTerminalTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ public class AbstractWindowsTerminalTest {
2727
public void testWriterBuffering() throws Exception {
2828
System.setProperty("org.jline.terminal.conemu.disable-activate", "true");
2929
StringWriter sw = new StringWriter();
30-
Terminal terminal = new AbstractWindowsTerminal(new AnsiWriter(new BufferedWriter(sw)), "name", TYPE_WINDOWS, Charset.defaultCharset(),
31-
false, Terminal.SignalHandler.SIG_DFL) {
30+
Terminal terminal = new AbstractWindowsTerminal<Object>(new AnsiWriter(new BufferedWriter(sw)), "name", TYPE_WINDOWS, Charset.defaultCharset(),
31+
false, Terminal.SignalHandler.SIG_DFL, null, null) {
3232
@Override
33-
protected int getConsoleMode() {
33+
protected int getConsoleMode(Object console) {
3434
return 0;
3535
}
3636
@Override
37-
protected void setConsoleMode(int mode) {
37+
protected void setConsoleMode(Object console, int mode) {
3838
}
3939
@Override
4040
protected boolean processConsoleInput() throws IOException {

0 commit comments

Comments
 (0)
Please sign in to comment.