From 393bca0d39324c7083ac3f676500e71a62f9a58f Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Sat, 7 Nov 2020 19:20:13 +0100 Subject: [PATCH] fix(compatibility): better stdin reading to fix various issues (#28) --- src/main.rs | 87 +++++++++++++++++++++++++----------------- src/os_input_output.rs | 4 +- src/screen.rs | 7 ++-- 3 files changed, 57 insertions(+), 41 deletions(-) diff --git a/src/main.rs b/src/main.rs index 87250ec2..698ec8e2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -151,8 +151,8 @@ pub fn start(mut os_input: Box, opts: Opt) { ScreenInstruction::VerticalSplit(pid) => { screen.vertical_split(pid); } - ScreenInstruction::WriteCharacter(byte) => { - screen.write_to_active_terminal(byte); + ScreenInstruction::WriteCharacter(bytes) => { + screen.write_to_active_terminal(bytes); } ScreenInstruction::ResizeLeft => { screen.resize_left(); @@ -240,41 +240,58 @@ pub fn start(mut os_input: Box, opts: Opt) { }).unwrap(); let mut stdin = os_input.get_stdin_reader(); + loop { - let mut buffer = [0; 1]; + let mut buffer = [0; 10]; // TODO: more accurately stdin.read(&mut buffer).expect("failed to read stdin"); - if buffer[0] == 10 { // ctrl-j - send_screen_instructions.send(ScreenInstruction::ResizeDown).unwrap(); - } else if buffer[0] == 11 { // ctrl-k - send_screen_instructions.send(ScreenInstruction::ResizeUp).unwrap(); - } else if buffer[0] == 16 { // ctrl-p - send_screen_instructions.send(ScreenInstruction::MoveFocus).unwrap(); - } else if buffer[0] == 8 { // ctrl-h - send_screen_instructions.send(ScreenInstruction::ResizeLeft).unwrap(); - } else if buffer[0] == 12 { // ctrl-l - send_screen_instructions.send(ScreenInstruction::ResizeRight).unwrap(); - } else if buffer[0] == 26 { // ctrl-z - send_pty_instructions.send(PtyInstruction::SpawnTerminal(None)).unwrap(); - } else if buffer[0] == 14 { // ctrl-n - send_pty_instructions.send(PtyInstruction::SpawnTerminalVertically(None)).unwrap(); - } else if buffer[0] == 2 { // ctrl-b - send_pty_instructions.send(PtyInstruction::SpawnTerminalHorizontally(None)).unwrap(); - } else if buffer[0] == 17 { // ctrl-q - send_screen_instructions.send(ScreenInstruction::Quit).unwrap(); - send_pty_instructions.send(PtyInstruction::Quit).unwrap(); - break; - } else if buffer[0] == 27 { // ctrl-[ - send_screen_instructions.send(ScreenInstruction::ScrollUp).unwrap(); - } else if buffer[0] == 29 { // ctrl-] - send_screen_instructions.send(ScreenInstruction::ScrollDown).unwrap(); - } else if buffer[0] == 24 { // ctrl-x - send_screen_instructions.send(ScreenInstruction::CloseFocusedPane).unwrap(); - } else if buffer[0] == 5 { // ctrl-e - send_screen_instructions.send(ScreenInstruction::ToggleActiveTerminalFullscreen).unwrap(); - } else { - // println!("\r buffer {:?} ", buffer[0]); - send_screen_instructions.send(ScreenInstruction::ClearScroll).unwrap(); - send_screen_instructions.send(ScreenInstruction::WriteCharacter(buffer[0])).unwrap(); + // uncomment this to print the entered character to a log file (/tmp/mosaic-log.txt) for debugging + // _debug_log_to_file(format!("buffer {:?}", buffer)); + match buffer { + [10, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-j + send_screen_instructions.send(ScreenInstruction::ResizeDown).unwrap(); + }, + [11, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-k + send_screen_instructions.send(ScreenInstruction::ResizeUp).unwrap(); + }, + [16, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-p + send_screen_instructions.send(ScreenInstruction::MoveFocus).unwrap(); + }, + [8, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-h + send_screen_instructions.send(ScreenInstruction::ResizeLeft).unwrap(); + }, + [12, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-l + send_screen_instructions.send(ScreenInstruction::ResizeRight).unwrap(); + }, + [26, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-z + send_pty_instructions.send(PtyInstruction::SpawnTerminal(None)).unwrap(); + }, + [14, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-n + send_pty_instructions.send(PtyInstruction::SpawnTerminalVertically(None)).unwrap(); + }, + [2, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-b + send_pty_instructions.send(PtyInstruction::SpawnTerminalHorizontally(None)).unwrap(); + }, + [17, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-q + send_screen_instructions.send(ScreenInstruction::Quit).unwrap(); + send_pty_instructions.send(PtyInstruction::Quit).unwrap(); + break; + }, + [27, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-[ + send_screen_instructions.send(ScreenInstruction::ScrollUp).unwrap(); + }, + [29, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-] + send_screen_instructions.send(ScreenInstruction::ScrollDown).unwrap(); + }, + [24, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-x + send_screen_instructions.send(ScreenInstruction::CloseFocusedPane).unwrap(); + }, + [5, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-e + send_screen_instructions.send(ScreenInstruction::ToggleActiveTerminalFullscreen).unwrap(); + }, + _ => { + send_screen_instructions.send(ScreenInstruction::ClearScroll).unwrap(); + send_screen_instructions.send(ScreenInstruction::WriteCharacter(buffer)).unwrap(); + } } }; diff --git a/src/os_input_output.rs b/src/os_input_output.rs index 04a5263c..6363d2e6 100644 --- a/src/os_input_output.rs +++ b/src/os_input_output.rs @@ -24,7 +24,6 @@ fn into_raw_mode(pid: RawFd) { Ok(_) => {}, Err(e) => panic!("error {:?}", e) }; - } pub fn get_terminal_size_using_fd(fd: RawFd) -> Winsize { @@ -94,7 +93,8 @@ fn handle_command_exit(mut child: Child) { fn spawn_terminal (file_to_open: Option) -> (RawFd, RawFd) { let (pid_primary, pid_secondary): (RawFd, RawFd) = { - match forkpty(None, None) { + let current_termios = tcgetattr(0).unwrap(); + match forkpty(None, Some(¤t_termios)) { Ok(fork_pty_res) => { let pid_primary = fork_pty_res.master; let pid_secondary = match fork_pty_res.fork_result { diff --git a/src/screen.rs b/src/screen.rs index e02f8e8f..fd4cc159 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -62,7 +62,7 @@ pub enum ScreenInstruction { NewPane(RawFd), HorizontalSplit(RawFd), VerticalSplit(RawFd), - WriteCharacter(u8), + WriteCharacter([u8; 10]), ResizeLeft, ResizeRight, ResizeDown, @@ -257,10 +257,9 @@ impl Screen { let terminal_output = self.terminals.get_mut(&pid).unwrap(); terminal_output.handle_event(event); } - pub fn write_to_active_terminal(&mut self, byte: u8) { + pub fn write_to_active_terminal(&mut self, mut bytes: [u8; 10]) { if let Some(active_terminal_id) = &self.get_active_terminal_id() { - let mut buffer = [byte]; - self.os_api.write_to_tty_stdin(*active_terminal_id, &mut buffer).expect("failed to write to terminal"); + self.os_api.write_to_tty_stdin(*active_terminal_id, &mut bytes).expect("failed to write to terminal"); self.os_api.tcdrain(*active_terminal_id).expect("failed to drain terminal"); } }