fix(TUI): proper arrow key handling — parse ESC sequences instead of treating as Esc
This commit is contained in:
@@ -52,12 +52,10 @@
|
||||
|
||||
Лаунчер использует **текстовый интерфейс (TUI)**:
|
||||
|
||||
- `W` / `S` (или `Ц` / `Ы`) — перемещение по меню
|
||||
- `W` / `S` (или `Ц` / `Ы`) или `↑` / `↓` — перемещение по меню
|
||||
- `ENTER` — выбор пункта
|
||||
- `ESC` или пункт «Назад» — возврат назад
|
||||
|
||||
> **Важно:** Стрелки ↑/↓ могут вызывать баги и краши. Используйте только `W`/`S`.
|
||||
|
||||
Если вы случайно кликнули мышкой в окне лаунчера и он «заморозился» — просто нажмите **любую клавишу** на клавиатуре.
|
||||
|
||||
### Расположение сборок
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
<artifactId>jansi</artifactId>
|
||||
<version>2.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jline</groupId>
|
||||
<artifactId>jline</artifactId>
|
||||
<version>3.24.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.tongfei</groupId>
|
||||
<artifactId>progressbar</artifactId>
|
||||
|
||||
@@ -149,7 +149,6 @@ public class LoginMenu {
|
||||
* если недоступно (IDE/терминал без TTY) — читаем обычным способом.
|
||||
*/
|
||||
private String readPassword(String prompt) throws IOException {
|
||||
// Создаём временный терминал для ввода пароля
|
||||
org.jline.terminal.Terminal passTerminal = org.jline.terminal.TerminalBuilder.builder()
|
||||
.system(true)
|
||||
.jna(true)
|
||||
@@ -165,6 +164,15 @@ public class LoginMenu {
|
||||
while (true) {
|
||||
int key = passTerminal.reader().read();
|
||||
|
||||
if (key == 27) {
|
||||
// Escape sequence — consume remaining bytes (arrow keys, etc.)
|
||||
int next = passTerminal.reader().read(50);
|
||||
if (next == 91) { // '[' — arrow key sequence
|
||||
passTerminal.reader().read(50); // consume 'A'/'B'/'C'/'D'
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key == 13 || key == 10) { // Enter
|
||||
passTerminal.writer().println();
|
||||
break;
|
||||
@@ -177,7 +185,7 @@ public class LoginMenu {
|
||||
} else if (key == 3) { // Ctrl+C
|
||||
passTerminal.writer().println();
|
||||
System.exit(0);
|
||||
} else if (key >= 32 && key < 127) { // Печатные символы
|
||||
} else if (key >= 32 && key < 127) { // Printable characters
|
||||
password.append((char) key);
|
||||
passTerminal.writer().print('*');
|
||||
passTerminal.writer().flush();
|
||||
|
||||
@@ -36,17 +36,30 @@ public class ArrowMenu {
|
||||
printPagedMenu();
|
||||
int key = terminal.reader().read();
|
||||
|
||||
if (key == 'w' || key == 'W' || key == 'ц' || key == 'Ц') { // Up
|
||||
if (key == 'w' || key == 'W' || key == 'ц' || key == 'Ц'
|
||||
|| key == 'k' || key == 'K' || key == 'л' || key == 'Л') { // Up / Arrow Up
|
||||
selected = (selected - 1 + options.size()) % options.size();
|
||||
}
|
||||
else if (key == 's' || key == 'S' || key == 'ы' || key == 'Ы') { // Down
|
||||
}
|
||||
else if (key == 's' || key == 'S' || key == 'ы' || key == 'Ы'
|
||||
|| key == 'j' || key == 'J' || key == 'о' || key == 'О') { // Down / Arrow Down
|
||||
selected = (selected + 1) % options.size();
|
||||
}
|
||||
}
|
||||
else if (key == 13 || key == 10) { // Enter
|
||||
return selected;
|
||||
}
|
||||
else if (key == 27) { // Esc
|
||||
return -1;
|
||||
}
|
||||
else if (key == 27) { // Esc or arrow escape seq
|
||||
int next = terminal.reader().read(50);
|
||||
if (next == 91) { // '[' — start of arrow escape sequence
|
||||
int arrow = terminal.reader().read(50);
|
||||
if (arrow == 65) { // 'A' — Up arrow
|
||||
selected = (selected - 1 + options.size()) % options.size();
|
||||
} else if (arrow == 66) { // 'B' — Down arrow
|
||||
selected = (selected + 1) % options.size();
|
||||
}
|
||||
// else — unknown escape seq, ignore
|
||||
} else {
|
||||
return -1; // genuine Esc
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -83,7 +96,7 @@ public class ArrowMenu {
|
||||
|
||||
// Подсказка внизу (фиксированная)
|
||||
sb.append("\n")
|
||||
.append(ZAnsi.white("W/S (Ц/Ы) - перемещение | Enter - выбрать | Esc - назад"));
|
||||
.append(ZAnsi.white("W/S (Ц/Ы) или ↑/↓ - перемещение | Enter - выбрать | Esc - назад"));
|
||||
|
||||
System.out.print(sb);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user