diff options
| author | Brooks J Rady <b.j.rady@gmail.com> | 2021-03-23 23:57:18 +0000 |
|---|---|---|
| committer | Brooks J Rady <b.j.rady@gmail.com> | 2021-03-23 23:57:18 +0000 |
| commit | 23df8e447a1e73b8e3536fbf9781f1aafcee2765 (patch) | |
| tree | eb462c458798ca3ff14f79f1e23d4d22c115f456 /src | |
| parent | Initial implementation of the update callback + upstream termion (diff) | |
| download | sl0ppij-23df8e447a1e73b8e3536fbf9781f1aafcee2765.tar.gz sl0ppij-23df8e447a1e73b8e3536fbf9781f1aafcee2765.tar.xz sl0ppij-23df8e447a1e73b8e3536fbf9781f1aafcee2765.zip | |
Move most key handling to the update() + event system
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/tab.rs | 16 | ||||
| -rw-r--r-- | src/common/errors.rs | 4 | ||||
| -rw-r--r-- | src/common/input/handler.rs | 18 | ||||
| -rw-r--r-- | src/common/mod.rs | 76 | ||||
| -rw-r--r-- | src/common/wasm_vm.rs | 5 |
5 files changed, 45 insertions, 74 deletions
diff --git a/src/client/tab.rs b/src/client/tab.rs index 1818672b..1a3f411d 100644 --- a/src/client/tab.rs +++ b/src/client/tab.rs @@ -1,11 +1,11 @@ //! `Tab`s holds multiple panes. It tracks their coordinates (x/y) and size, //! as well as how they should be resized -use crate::common::{AppInstruction, SenderWithContext}; +use crate::common::{input::handler::parse_keys, AppInstruction, SenderWithContext}; use crate::layout::Layout; use crate::panes::{PaneId, PositionAndSize, TerminalPane}; use crate::pty_bus::{PtyInstruction, VteEvent}; -use crate::wasm_vm::{PluginInputType, PluginInstruction}; +use crate::wasm_vm::PluginInstruction; use crate::{boundaries::Boundaries, panes::PluginPane}; use crate::{os_input_output::OsApi, utils::shared::pad_to_size}; use std::os::unix::io::RawFd; @@ -14,6 +14,7 @@ use std::{ collections::{BTreeMap, HashSet}, }; use std::{io::Write, sync::mpsc::channel}; +use zellij_tile::data::Event; const CURSOR_HEIGHT_WIDTH_RATIO: usize = 4; // this is not accurate and kind of a magic number, TODO: look into this const MIN_TERMINAL_HEIGHT: usize = 2; @@ -553,12 +554,11 @@ impl Tab { .expect("failed to drain terminal"); } Some(PaneId::Plugin(pid)) => { - self.send_plugin_instructions - .send(PluginInstruction::Input( - PluginInputType::Normal(pid), - input_bytes, - )) - .unwrap(); + for key in parse_keys(&input_bytes) { + self.send_plugin_instructions + .send(PluginInstruction::Update(Some(pid), Event::KeyPress(key))) + .unwrap() + } } _ => {} } diff --git a/src/common/errors.rs b/src/common/errors.rs index 11d13c7e..b12a57a1 100644 --- a/src/common/errors.rs +++ b/src/common/errors.rs @@ -281,7 +281,6 @@ pub enum PluginContext { Update, Render, Input, - GlobalInput, Unload, Quit, Tabs, @@ -291,10 +290,9 @@ impl From<&PluginInstruction> for PluginContext { fn from(plugin_instruction: &PluginInstruction) -> Self { match *plugin_instruction { PluginInstruction::Load(..) => PluginContext::Load, - PluginInstruction::Update(_) => PluginContext::Update, + PluginInstruction::Update(..) => PluginContext::Update, PluginInstruction::Render(..) => PluginContext::Render, PluginInstruction::Input(..) => PluginContext::Input, - PluginInstruction::GlobalInput(_) => PluginContext::GlobalInput, PluginInstruction::Unload(_) => PluginContext::Unload, PluginInstruction::Quit => PluginContext::Quit, PluginInstruction::UpdateTabs(..) => PluginContext::Tabs, diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index 90afb64c..4b948cbf 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -10,8 +10,8 @@ use crate::screen::ScreenInstruction; use crate::wasm_vm::{NaughtyEventType, PluginInputType, PluginInstruction}; use crate::CommandIsExecuting; -use termion::input::TermReadEventsAndRaw; -use zellij_tile::data::{Event, Help, InputMode, Key}; +use termion::input::{TermRead, TermReadEventsAndRaw}; +use zellij_tile::data::{Help, InputMode, Key}; use super::keybinds::key_to_actions; @@ -61,19 +61,15 @@ impl InputHandler { 'input_loop: loop { //@@@ I think this should actually just iterate over stdin directly let stdin_buffer = self.os_input.read_from_stdin(); - // FIXME: Kill me someday (soon) - drop( - self.send_plugin_instructions - .send(PluginInstruction::GlobalInput(stdin_buffer.clone())), - ); for key_result in stdin_buffer.events_and_raw() { match key_result { Ok((event, raw_bytes)) => match event { termion::event::Event::Key(key) => { let key = cast_termion_key(key); + // FIXME: This is a bit of a hack to get resizing to work! drop( - self.send_plugin_instructions - .send(PluginInstruction::Update(Event::KeyPress(key))), + self.send_screen_instructions + .send(ScreenInstruction::Render), ); // FIXME this explicit break is needed because the current test // framework relies on it to not create dead threads that loop @@ -327,6 +323,10 @@ pub fn input_loop( .handle_input(); } +pub fn parse_keys(input_bytes: &[u8]) -> Vec<Key> { + input_bytes.keys().flatten().map(cast_termion_key).collect() +} + // FIXME: This is an absolutely cursed function that should be destroyed as soon // as an alternative that doesn't touch zellij-tile can be developed... fn cast_termion_key(event: termion::event::Key) -> Key { diff --git a/src/common/mod.rs b/src/common/mod.rs index 70edcea8..b8a4c671 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -17,6 +17,7 @@ use std::{collections::HashMap, fs}; use std::{ collections::HashSet, io::Write, + str::FromStr, sync::{Arc, Mutex}, }; @@ -40,7 +41,7 @@ use wasm_vm::{ }; use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value}; use wasmer_wasi::{Pipe, WasiState}; -use zellij_tile::data::{InputMode, Key}; +use zellij_tile::data::{EventType, InputMode, Key}; #[derive(Serialize, Deserialize, Debug)] pub enum ApiCommand { @@ -549,16 +550,21 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { pid_tx.send(plugin_id).unwrap(); plugin_id += 1; } - PluginInstruction::Update(event) => { - for (instance, plugin_env) in plugin_map.values() { - let update = instance.exports.get_function("update").unwrap(); - - wasi_write_string( - &plugin_env.wasi_env, - &serde_json::to_string(&event).unwrap(), - ); - update.call(&[]).unwrap(); + PluginInstruction::Update(pid, event) => { + for (&i, (instance, plugin_env)) in &plugin_map { + let subs = plugin_env.subscriptions.lock().unwrap(); + // FIXME: This is very janky... Maybe I should write my own macro for Event -> EventType? + let event_type = EventType::from_str(&event.to_string()).unwrap(); + if pid.is_none() || pid == Some(i) && subs.contains(&event_type) { + let update = instance.exports.get_function("update").unwrap(); + wasi_write_string( + &plugin_env.wasi_env, + &serde_json::to_string(&event).unwrap(), + ); + update.call(&[]).unwrap(); + } } + drop(send_screen_instructions.send(ScreenInstruction::Render)); } PluginInstruction::Render(buf_tx, pid, rows, cols) => { let (instance, plugin_env) = plugin_map.get(&pid).unwrap(); @@ -587,11 +593,15 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { } // FIXME: Deduplicate this with the callback below! PluginInstruction::Input(input_type, input_bytes) => { - match input_type { - PluginInputType::Normal(pid) => { - let (instance, plugin_env) = plugin_map.get(&pid).unwrap(); - let handle_key = - instance.exports.get_function("handle_key").unwrap(); + if let PluginInputType::Event(event) = input_type { + for (instance, plugin_env) in plugin_map.values() { + if !plugin_env.events.contains(&event) { + continue; + } + let handle_key = instance + .exports + .get_function(handler_map.get(&event).unwrap()) + .unwrap(); for key in input_bytes.keys().flatten() { let key = cast_termion_key(key); wasi_write_string( @@ -601,45 +611,9 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) { handle_key.call(&[]).unwrap(); } } - PluginInputType::Event(event) => { - for (instance, plugin_env) in plugin_map.values() { - if !plugin_env.events.contains(&event) { - continue; - } - let handle_key = instance - .exports - .get_function(handler_map.get(&event).unwrap()) - .unwrap(); - for key in input_bytes.keys().flatten() { - let key = cast_termion_key(key); - wasi_write_string( - &plugin_env.wasi_env, - &serde_json::to_string(&key).unwrap(), - ); - handle_key.call(&[]).unwrap(); - } - } - } } drop(send_screen_instructions.send(ScreenInstruction::Render)); } - PluginInstruction::GlobalInput(input_bytes) => { - // FIXME: Set up an event subscription system, and timed callbacks - for (instance, plugin_env) in plugin_map.values() { - let handler = - instance.exports.get_function("handle_global_key").unwrap(); - for key in input_bytes.keys().flatten() { - let key = cast_termion_key(key); - wasi_write_string( - &plugin_env.wasi_env, - &serde_json::to_string(&key).unwrap(), - ); - handler.call(&[]).unwrap(); - } - } - - drop(send_screen_instructions.send(ScreenInstruction::Render)); - } PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)), PluginInstruction::Quit => break, } diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs index 2f2a0cf6..24b947d6 100644 --- a/src/common/wasm_vm.rs +++ b/src/common/wasm_vm.rs @@ -30,10 +30,9 @@ pub enum PluginInputType { #[derive(Clone, Debug)] pub enum PluginInstruction { Load(Sender<u32>, PathBuf, Vec<NaughtyEventType>), - Update(Event), + Update(Option<u32>, Event), // Focused plugin / broadcast, event data Render(Sender<String>, u32, usize, usize), // String buffer, plugin id, rows, cols - Input(PluginInputType, Vec<u8>), // plugin id, input bytes - GlobalInput(Vec<u8>), // input bytes + Input(PluginInputType, Vec<u8>), // plugin id, input bytes Unload(u32), UpdateTabs(Vec<TabInfo>), // num tabs, active tab Quit, |
