Fix after rebase

This commit is contained in:
Kunal Mohan 2021-04-04 01:24:46 +05:30
parent 223ee743e1
commit 2a648187fc
11 changed files with 117 additions and 46 deletions

12
Cargo.lock generated
View file

@ -132,7 +132,7 @@ dependencies = [
"event-listener", "event-listener",
"futures-lite", "futures-lite",
"once_cell", "once_cell",
"signal-hook 0.3.6", "signal-hook",
"winapi", "winapi",
] ]
@ -1561,16 +1561,6 @@ dependencies = [
"opaque-debug", "opaque-debug",
] ]
[[package]]
name = "signal-hook"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]] [[package]]
name = "signal-hook" name = "signal-hook"
version = "0.3.6" version = "0.3.6"

View file

@ -69,6 +69,23 @@ pub fn start_client(mut os_input: Box<dyn ClientOsApi>) {
move || input_loop(os_input, command_is_executing, send_client_instructions) move || input_loop(os_input, command_is_executing, send_client_instructions)
}); });
let _signal_thread = thread::Builder::new()
.name("signal_listener".to_string())
.spawn({
let os_input = os_input.clone();
move || {
os_input.receive_sigwinch(Box::new({
let os_api = os_input.clone();
move || {
os_api.send_to_server(ServerInstruction::terminal_resize(
os_api.get_terminal_size_using_fd(0),
));
}
}));
}
})
.unwrap();
let router_thread = thread::Builder::new() let router_thread = thread::Builder::new()
.name("router".to_string()) .name("router".to_string())
.spawn({ .spawn({

View file

@ -1,4 +1,4 @@
use crate::os_input_output::OsApi; use crate::os_input_output::ServerOsApi;
use crate::panes::{PaneId, PositionAndSize}; use crate::panes::{PaneId, PositionAndSize};
use crate::tab::Pane; use crate::tab::Pane;
use std::{ use std::{
@ -8,7 +8,7 @@ use std::{
pub struct PaneResizer<'a> { pub struct PaneResizer<'a> {
panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>, panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
os_api: &'a mut Box<dyn OsApi>, os_api: &'a mut Box<dyn ServerOsApi>,
} }
// TODO: currently there are some functions here duplicated with Tab // TODO: currently there are some functions here duplicated with Tab
@ -17,7 +17,7 @@ pub struct PaneResizer<'a> {
impl<'a> PaneResizer<'a> { impl<'a> PaneResizer<'a> {
pub fn new( pub fn new(
panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>, panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
os_api: &'a mut Box<dyn OsApi>, os_api: &'a mut Box<dyn ServerOsApi>,
) -> Self { ) -> Self {
PaneResizer { panes, os_api } PaneResizer { panes, os_api }
} }

View file

@ -2,22 +2,24 @@
//! as well as how they should be resized //! as well as how they should be resized
use crate::boundaries::colors; use crate::boundaries::colors;
use crate::client::pane_resizer::PaneResizer;
use crate::common::{input::handler::parse_keys, SenderWithContext}; use crate::common::{input::handler::parse_keys, SenderWithContext};
use crate::layout::Layout; use crate::layout::Layout;
use crate::os_input_output::ServerOsApi; use crate::os_input_output::ServerOsApi;
use crate::panes::{PaneId, PositionAndSize, TerminalPane}; use crate::panes::{PaneId, PositionAndSize, TerminalPane};
use crate::pty_bus::{PtyInstruction, VteEvent}; use crate::pty_bus::{PtyInstruction, VteEvent};
use crate::server::ServerInstruction; use crate::server::ServerInstruction;
use crate::utils::shared::pad_to_size; use crate::utils::shared::adjust_to_size;
use crate::wasm_vm::PluginInstruction; use crate::wasm_vm::PluginInstruction;
use crate::{boundaries::Boundaries, panes::PluginPane}; use crate::{boundaries::Boundaries, panes::PluginPane};
use serde::{Deserialize, Serialize};
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
use std::sync::mpsc::channel; use std::sync::mpsc::channel;
use std::{ use std::{
cmp::Reverse, cmp::Reverse,
collections::{BTreeMap, HashSet}, collections::{BTreeMap, HashSet},
}; };
use zellij_tile::data::{Event, InputMode}; use zellij_tile::data::{Event, ModeInfo};
const CURSOR_HEIGHT_WIDTH_RATIO: usize = 4; // this is not accurate and kind of a magic number, TODO: look into this const CURSOR_HEIGHT_WIDTH_RATIO: usize = 4; // this is not accurate and kind of a magic number, TODO: look into this
@ -729,9 +731,14 @@ impl Tab {
); );
let hide_cursor = "\u{1b}[?25l"; let hide_cursor = "\u{1b}[?25l";
output.push_str(hide_cursor); output.push_str(hide_cursor);
for (kind, terminal) in self.panes.iter_mut() { if self.should_clear_display_before_rendering {
if !self.panes_to_hide.contains(&terminal.pid()) { let clear_display = "\u{1b}[2J";
match self.active_terminal.unwrap() == terminal.pid() { output.push_str(clear_display);
self.should_clear_display_before_rendering = false;
}
for (kind, pane) in self.panes.iter_mut() {
if !self.panes_to_hide.contains(&pane.pid()) {
match self.active_terminal.unwrap() == pane.pid() {
true => { true => {
pane.set_active_at(Instant::now()); pane.set_active_at(Instant::now());
boundaries.add_rect(pane.as_ref(), self.mode_info.mode, Some(self.colors)) boundaries.add_rect(pane.as_ref(), self.mode_info.mode, Some(self.colors))

View file

@ -259,7 +259,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenInstruction::CloseTab => ScreenContext::CloseTab, ScreenInstruction::CloseTab => ScreenContext::CloseTab,
ScreenInstruction::GoToTab(_) => ScreenContext::GoToTab, ScreenInstruction::GoToTab(_) => ScreenContext::GoToTab,
ScreenInstruction::UpdateTabName(_) => ScreenContext::UpdateTabName, ScreenInstruction::UpdateTabName(_) => ScreenContext::UpdateTabName,
ScreenInstruction::TerminalResize => ScreenContext::TerminalResize, ScreenInstruction::TerminalResize(_) => ScreenContext::TerminalResize,
ScreenInstruction::ChangeMode(_) => ScreenContext::ChangeMode, ScreenInstruction::ChangeMode(_) => ScreenContext::ChangeMode,
ScreenInstruction::ToggleActiveSyncPanes => ScreenContext::ToggleActiveSyncPanes, ScreenInstruction::ToggleActiveSyncPanes => ScreenContext::ToggleActiveSyncPanes,
} }

View file

@ -127,7 +127,7 @@ impl InputHandler {
Event::ModeUpdate(get_mode_info(mode)), Event::ModeUpdate(get_mode_info(mode)),
)); ));
self.os_input self.os_input
.send_to_server(ServerInstruction::change_input_mode(mode)); .send_to_server(ServerInstruction::change_mode(get_mode_info(mode)));
self.os_input.send_to_server(ServerInstruction::render()); self.os_input.send_to_server(ServerInstruction::render());
} }
Action::Resize(direction) => { Action::Resize(direction) => {

View file

@ -7,6 +7,7 @@ use nix::sys::wait::waitpid;
use nix::unistd; use nix::unistd;
use nix::unistd::{ForkResult, Pid}; use nix::unistd::{ForkResult, Pid};
use serde::Serialize; use serde::Serialize;
use signal_hook::{consts::signal::*, iterator::Signals};
use std::env; use std::env;
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
@ -334,6 +335,7 @@ pub trait ClientOsApi: Send + Sync {
fn client_recv(&self) -> (ClientInstruction, ErrorContext); fn client_recv(&self) -> (ClientInstruction, ErrorContext);
/// Setup the client IpcChannel and notify server of new client /// Setup the client IpcChannel and notify server of new client
fn connect_to_server(&mut self, full_screen_ws: PositionAndSize); fn connect_to_server(&mut self, full_screen_ws: PositionAndSize);
fn receive_sigwinch(&self, cb: Box<dyn Fn()>);
} }
impl ClientOsApi for ClientOsInputOutput { impl ClientOsApi for ClientOsInputOutput {
@ -389,6 +391,20 @@ impl ClientOsApi for ClientOsInputOutput {
.recv() .recv()
.unwrap() .unwrap()
} }
fn receive_sigwinch(&self, cb: Box<dyn Fn()>) {
let mut signals = Signals::new(&[SIGWINCH, SIGTERM, SIGINT, SIGQUIT]).unwrap();
for signal in signals.forever() {
match signal {
SIGWINCH => {
cb();
}
SIGTERM | SIGINT | SIGQUIT => {
break;
}
_ => unreachable!(),
}
}
}
} }
impl Clone for Box<dyn ClientOsApi> { impl Clone for Box<dyn ClientOsApi> {

View file

@ -58,7 +58,7 @@ pub enum ScreenInstruction {
CloseTab, CloseTab,
GoToTab(u32), GoToTab(u32),
UpdateTabName(Vec<u8>), UpdateTabName(Vec<u8>),
TerminalResize, TerminalResize(PositionAndSize),
ChangeMode(ModeInfo), ChangeMode(ModeInfo),
} }
@ -83,7 +83,7 @@ pub struct Screen {
active_tab_index: Option<usize>, active_tab_index: Option<usize>,
/// The [`ClientOsApi`] this [`Screen`] uses. /// The [`ClientOsApi`] this [`Screen`] uses.
os_api: Box<dyn ServerOsApi>, os_api: Box<dyn ServerOsApi>,
input_mode: InputMode, mode_info: ModeInfo,
} }
impl Screen { impl Screen {
@ -233,8 +233,7 @@ impl Screen {
} }
} }
pub fn resize_to_screen(&mut self) { pub fn resize_to_screen(&mut self, new_screen_size: PositionAndSize) {
let new_screen_size = self.os_api.get_terminal_size_using_fd(0);
self.full_screen_ws = new_screen_size; self.full_screen_ws = new_screen_size;
for (_, tab) in self.tabs.iter_mut() { for (_, tab) in self.tabs.iter_mut() {
tab.resize_whole_tab(new_screen_size); tab.resize_whole_tab(new_screen_size);

View file

@ -12,7 +12,7 @@ use std::{
}; };
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value}; use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
use wasmer_wasi::{Pipe, WasiState}; use wasmer_wasi::{Pipe, WasiState};
use zellij_tile::data::{Event, EventType, InputMode}; use zellij_tile::data::{Event, EventType, ModeInfo};
use crate::cli::CliArgs; use crate::cli::CliArgs;
use crate::client::ClientInstruction; use crate::client::ClientInstruction;
@ -168,12 +168,15 @@ impl ServerInstruction {
pub fn update_tab_name(tab_ids: Vec<u8>) -> Self { pub fn update_tab_name(tab_ids: Vec<u8>) -> Self {
Self::ToScreen(ScreenInstruction::UpdateTabName(tab_ids)) Self::ToScreen(ScreenInstruction::UpdateTabName(tab_ids))
} }
pub fn change_input_mode(input_mode: InputMode) -> Self { pub fn change_mode(mode_info: ModeInfo) -> Self {
Self::ToScreen(ScreenInstruction::ChangeInputMode(input_mode)) Self::ToScreen(ScreenInstruction::ChangeMode(mode_info))
} }
pub fn pty(fd: RawFd, event: VteEvent) -> Self { pub fn pty(fd: RawFd, event: VteEvent) -> Self {
Self::ToScreen(ScreenInstruction::Pty(fd, event)) Self::ToScreen(ScreenInstruction::Pty(fd, event))
} }
pub fn terminal_resize(new_size: PositionAndSize) -> Self {
Self::ToScreen(ScreenInstruction::TerminalResize(new_size))
}
} }
struct ClientMetaData { struct ClientMetaData {
@ -450,7 +453,7 @@ fn init_client(
&full_screen_ws, &full_screen_ws,
os_input, os_input,
max_panes, max_panes,
InputMode::Normal, ModeInfo::default(),
); );
loop { loop {
let (event, mut err_ctx) = screen let (event, mut err_ctx) = screen
@ -625,8 +628,11 @@ fn init_client(
.send(ServerInstruction::DoneUpdatingTabs) .send(ServerInstruction::DoneUpdatingTabs)
.unwrap(); .unwrap();
} }
ScreenInstruction::ChangeInputMode(input_mode) => { ScreenInstruction::ChangeMode(mode_info) => {
screen.change_input_mode(input_mode); screen.change_mode(mode_info);
}
ScreenInstruction::TerminalResize(new_size) => {
screen.resize_to_screen(new_size);
} }
ScreenInstruction::Exit => { ScreenInstruction::Exit => {
break; break;

View file

@ -3,8 +3,7 @@ use std::collections::{HashMap, VecDeque};
use std::io::Write; use std::io::Write;
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{mpsc, Arc, Condvar, Mutex};
use std::sync::{mpsc, Arc, Mutex};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use crate::client::ClientInstruction; use crate::client::ClientInstruction;
@ -13,8 +12,7 @@ use crate::errors::ErrorContext;
use crate::os_input_output::{ClientOsApi, ServerOsApi}; use crate::os_input_output::{ClientOsApi, ServerOsApi};
use crate::server::ServerInstruction; use crate::server::ServerInstruction;
use crate::tests::possible_tty_inputs::{get_possible_tty_inputs, Bytes}; use crate::tests::possible_tty_inputs::{get_possible_tty_inputs, Bytes};
use crate::utils::shared::default_palette; use crate::tests::utils::commands::{QUIT, SLEEP};
use zellij_tile::data::Palette;
const MIN_TIME_BETWEEN_SNAPSHOTS: Duration = Duration::from_millis(150); const MIN_TIME_BETWEEN_SNAPSHOTS: Duration = Duration::from_millis(150);
@ -76,11 +74,12 @@ pub struct FakeInputOutput {
win_sizes: Arc<Mutex<HashMap<RawFd, PositionAndSize>>>, win_sizes: Arc<Mutex<HashMap<RawFd, PositionAndSize>>>,
possible_tty_inputs: HashMap<u16, Bytes>, possible_tty_inputs: HashMap<u16, Bytes>,
last_snapshot_time: Arc<Mutex<Instant>>, last_snapshot_time: Arc<Mutex<Instant>>,
started_reading_from_pty: Arc<AtomicBool>,
client_sender: SenderWithContext<ClientInstruction>, client_sender: SenderWithContext<ClientInstruction>,
client_receiver: Arc<Mutex<mpsc::Receiver<(ClientInstruction, ErrorContext)>>>, client_receiver: Arc<Mutex<mpsc::Receiver<(ClientInstruction, ErrorContext)>>>,
server_sender: SenderWithContext<ServerInstruction>, server_sender: SenderWithContext<ServerInstruction>,
server_receiver: Arc<Mutex<mpsc::Receiver<(ServerInstruction, ErrorContext)>>>, server_receiver: Arc<Mutex<mpsc::Receiver<(ServerInstruction, ErrorContext)>>>,
should_trigger_sigwinch: Arc<(Mutex<bool>, Condvar)>,
sigwinch_event: Option<PositionAndSize>,
} }
impl FakeInputOutput { impl FakeInputOutput {
@ -108,11 +107,12 @@ impl FakeInputOutput {
io_events: Arc::new(Mutex::new(vec![])), io_events: Arc::new(Mutex::new(vec![])),
win_sizes: Arc::new(Mutex::new(win_sizes)), win_sizes: Arc::new(Mutex::new(win_sizes)),
possible_tty_inputs: get_possible_tty_inputs(), possible_tty_inputs: get_possible_tty_inputs(),
started_reading_from_pty: Arc::new(AtomicBool::new(false)),
server_receiver: Arc::new(Mutex::new(server_receiver)), server_receiver: Arc::new(Mutex::new(server_receiver)),
server_sender, server_sender,
client_receiver: Arc::new(Mutex::new(client_receiver)), client_receiver: Arc::new(Mutex::new(client_receiver)),
client_sender, client_sender,
should_trigger_sigwinch: Arc::new((Mutex::new(false), Condvar::new())),
sigwinch_event: None,
} }
} }
pub fn with_tty_inputs(mut self, tty_inputs: HashMap<u16, Bytes>) -> Self { pub fn with_tty_inputs(mut self, tty_inputs: HashMap<u16, Bytes>) -> Self {
@ -171,14 +171,24 @@ impl ClientOsApi for FakeInputOutput {
::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS - last_snapshot_time.elapsed()); ::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS - last_snapshot_time.elapsed());
} }
} }
if self.stdin_commands.lock().unwrap().len() == 1 { let command = self
std::thread::sleep(Duration::from_millis(100)); .stdin_commands
}
self.stdin_commands
.lock() .lock()
.unwrap() .unwrap()
.pop_front() .pop_front()
.unwrap_or(vec![]) .unwrap_or(vec![]);
if command == SLEEP {
std::thread::sleep(std::time::Duration::from_millis(200));
} else if command == QUIT && self.sigwinch_event.is_some() {
let (lock, cvar) = &*self.should_trigger_sigwinch;
let mut should_trigger_sigwinch = lock.lock().unwrap();
*should_trigger_sigwinch = true;
cvar.notify_one();
::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS); // give some time for the app to resize before quitting
} else if command == QUIT {
::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS);
}
command
} }
fn get_stdout_writer(&self) -> Box<dyn Write> { fn get_stdout_writer(&self) -> Box<dyn Write> {
Box::new(self.stdout_writer.clone()) Box::new(self.stdout_writer.clone())
@ -199,6 +209,16 @@ impl ClientOsApi for FakeInputOutput {
fn client_recv(&self) -> (ClientInstruction, ErrorContext) { fn client_recv(&self) -> (ClientInstruction, ErrorContext) {
self.client_receiver.lock().unwrap().recv().unwrap() self.client_receiver.lock().unwrap().recv().unwrap()
} }
fn receive_sigwinch(&self, cb: Box<dyn Fn()>) {
if self.sigwinch_event.is_some() {
let (lock, cvar) = &*self.should_trigger_sigwinch;
let mut should_trigger_sigwinch = lock.lock().unwrap();
while !*should_trigger_sigwinch {
should_trigger_sigwinch = cvar.wait(should_trigger_sigwinch).unwrap();
}
cb();
}
}
} }
impl ServerOsApi for FakeInputOutput { impl ServerOsApi for FakeInputOutput {

View file

@ -30,7 +30,11 @@ pub fn window_width_decrease_with_one_pane() {
..Default::default() ..Default::default()
}); });
let opts = CliArgs::default(); let opts = CliArgs::default();
start(Box::new(fake_input_output.clone()), opts, Config::default()); start(
Box::new(fake_input_output.clone()),
opts,
Box::new(fake_input_output.clone()),
);
let output_frames = fake_input_output let output_frames = fake_input_output
.stdout_writer .stdout_writer
.output_frames .output_frames
@ -61,7 +65,11 @@ pub fn window_width_increase_with_one_pane() {
..Default::default() ..Default::default()
}); });
let opts = CliArgs::default(); let opts = CliArgs::default();
start(Box::new(fake_input_output.clone()), opts, Config::default()); start(
Box::new(fake_input_output.clone()),
opts,
Box::new(fake_input_output.clone()),
);
let output_frames = fake_input_output let output_frames = fake_input_output
.stdout_writer .stdout_writer
.output_frames .output_frames
@ -92,7 +100,11 @@ pub fn window_height_increase_with_one_pane() {
..Default::default() ..Default::default()
}); });
let opts = CliArgs::default(); let opts = CliArgs::default();
start(Box::new(fake_input_output.clone()), opts, Config::default()); start(
Box::new(fake_input_output.clone()),
opts,
Box::new(fake_input_output.clone()),
);
let output_frames = fake_input_output let output_frames = fake_input_output
.stdout_writer .stdout_writer
.output_frames .output_frames
@ -123,7 +135,11 @@ pub fn window_width_and_height_decrease_with_one_pane() {
..Default::default() ..Default::default()
}); });
let opts = CliArgs::default(); let opts = CliArgs::default();
start(Box::new(fake_input_output.clone()), opts, Config::default()); start(
Box::new(fake_input_output.clone()),
opts,
Box::new(fake_input_output.clone()),
);
let output_frames = fake_input_output let output_frames = fake_input_output
.stdout_writer .stdout_writer
.output_frames .output_frames