aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrooks J Rady <b.j.rady@gmail.com>2021-03-23 23:57:18 +0000
committerBrooks J Rady <b.j.rady@gmail.com>2021-03-23 23:57:18 +0000
commit23df8e447a1e73b8e3536fbf9781f1aafcee2765 (patch)
treeeb462c458798ca3ff14f79f1e23d4d22c115f456 /src
parentInitial implementation of the update callback + upstream termion (diff)
downloadsl0ppij-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.rs16
-rw-r--r--src/common/errors.rs4
-rw-r--r--src/common/input/handler.rs18
-rw-r--r--src/common/mod.rs76
-rw-r--r--src/common/wasm_vm.rs5
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,