diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2508fe..ae5491b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * Fix crash when padding before widechar (https://github.com/zellij-org/zellij/pull/540) * Do not lag when reading input too fast (https://github.com/zellij-org/zellij/pull/536) * Session name optional in attach command (https://github.com/zellij-org/zellij/pull/542) +* Fix build on platforms with TIOCGWINSZ / ioctl() integer type mismatch (https://github.com/zellij-org/zellij/pull/547) +* Fix(ui): session mode should be disabled in locked mode (https://github.com/zellij-org/zellij/pull/548) +* Add option to start in arbitrary modes (https://github.com/zellij-org/zellij/pull/513) +* Attaching to a session respects the `default_mode` setting of the client (https://github.com/zellij-org/zellij/pull/549) ## [0.12.1] - 2021-05-28 * HOTFIX: fix Zellij not responding to input on certain terminals (https://github.com/zellij-org/zellij/issues/538) diff --git a/default-plugins/status-bar/src/first_line.rs b/default-plugins/status-bar/src/first_line.rs index 7a678cdc..70633195 100644 --- a/default-plugins/status-bar/src/first_line.rs +++ b/default-plugins/status-bar/src/first_line.rs @@ -254,7 +254,7 @@ pub fn ctrl_keys(help: &ModeInfo, max_len: usize, separator: &str) -> LinePart { CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Scroll), - CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Session), + CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Quit), ], colored_elements, diff --git a/src/main.rs b/src/main.rs index b9147fab..97ad3dee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ use zellij_utils::{ cli::{CliArgs, Command, Sessions}, consts::{ZELLIJ_TMP_DIR, ZELLIJ_TMP_LOG_DIR}, input::config::Config, + input::options::Options, logging::*, setup::{get_default_data_dir, Setup}, structopt::StructOpt, @@ -63,11 +64,14 @@ pub fn main() { } else { session_name = Some(get_active_session()); } + + let config_options = Options::from_cli(&config.options, opts.command.clone()); + start_client( Box::new(os_input), opts, config, - ClientInfo::Attach(session_name.unwrap(), force), + ClientInfo::Attach(session_name.unwrap(), force, config_options), ); } else { let session_name = opts diff --git a/zellij-client/src/input_handler.rs b/zellij-client/src/input_handler.rs index 70f6e982..65181e51 100644 --- a/zellij-client/src/input_handler.rs +++ b/zellij-client/src/input_handler.rs @@ -33,9 +33,10 @@ impl InputHandler { command_is_executing: CommandIsExecuting, config: Config, send_client_instructions: SenderWithContext, + mode: InputMode, ) -> Self { InputHandler { - mode: InputMode::Normal, + mode, os_input, config, command_is_executing, @@ -181,12 +182,14 @@ pub(crate) fn input_loop( config: Config, command_is_executing: CommandIsExecuting, send_client_instructions: SenderWithContext, + default_mode: InputMode, ) { let _handler = InputHandler::new( os_input, command_is_executing, config, send_client_instructions, + default_mode, ) .handle_input(); } diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index 7ea4f81e..ece154ea 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -77,7 +77,7 @@ fn spawn_server(socket_path: &Path) -> io::Result<()> { #[derive(Debug, Clone)] pub enum ClientInfo { - Attach(String, bool), + Attach(String, bool, Options), New(String), } @@ -117,11 +117,11 @@ pub fn start_client( #[cfg(not(any(feature = "test", test)))] let first_msg = match info { - ClientInfo::Attach(name, force) => { + ClientInfo::Attach(name, force, config_options) => { SESSION_NAME.set(name).unwrap(); std::env::set_var(&"ZELLIJ_SESSION_NAME", SESSION_NAME.get().unwrap()); - ClientToServerMsg::AttachClient(client_attributes, force) + ClientToServerMsg::AttachClient(client_attributes, force, config_options) } ClientInfo::New(name) => { SESSION_NAME.set(name).unwrap(); @@ -132,14 +132,18 @@ pub fn start_client( ClientToServerMsg::NewClient( client_attributes, Box::new(opts), - Box::new(config_options), + Box::new(config_options.clone()), ) } }; #[cfg(any(feature = "test", test))] let first_msg = { let _ = SESSION_NAME.set("".into()); - ClientToServerMsg::NewClient(client_attributes, Box::new(opts), Box::new(config_options)) + ClientToServerMsg::NewClient( + client_attributes, + Box::new(opts), + Box::new(config_options.clone()), + ) }; os_input.connect_to_server(&*ZELLIJ_IPC_PIPE); @@ -173,12 +177,14 @@ pub fn start_client( let send_client_instructions = send_client_instructions.clone(); let command_is_executing = command_is_executing.clone(); let os_input = os_input.clone(); + let default_mode = config_options.default_mode.unwrap_or_default(); move || { input_loop( os_input, config, command_is_executing, send_client_instructions, + default_mode, ) } }); diff --git a/zellij-client/src/os_input_output.rs b/zellij-client/src/os_input_output.rs index 0606ae37..405422ab 100644 --- a/zellij-client/src/os_input_output.rs +++ b/zellij-client/src/os_input_output.rs @@ -45,7 +45,13 @@ pub(crate) fn get_terminal_size_using_fd(fd: RawFd) -> PositionAndSize { ws_ypixel: 0, }; - unsafe { ioctl(fd, TIOCGWINSZ, &mut winsize) }; + // TIOCGWINSZ is an u32, but the second argument to ioctl is u64 on + // some platforms. When checked on Linux, clippy will complain about + // useless conversion. + #[allow(clippy::useless_conversion)] + unsafe { + ioctl(fd, TIOCGWINSZ.into(), &mut winsize) + }; PositionAndSize::from(winsize) } diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index 8f1ad73a..1691420e 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -15,7 +15,7 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex, RwLock}; use std::thread; use wasmer::Store; -use zellij_tile::data::{Event, InputMode,Palette, PluginCapabilities}; +use zellij_tile::data::{Event, Palette, PluginCapabilities}; use crate::{ os_input_output::ServerOsApi, @@ -44,7 +44,7 @@ pub(crate) enum ServerInstruction { ClientExit, Error(String), DetachSession, - AttachClient(ClientAttributes, bool), + AttachClient(ClientAttributes, bool, Options), } impl From for ServerInstruction { @@ -53,8 +53,8 @@ impl From for ServerInstruction { ClientToServerMsg::NewClient(attrs, opts, options) => { ServerInstruction::NewClient(attrs, opts, options) } - ClientToServerMsg::AttachClient(attrs, force) => { - ServerInstruction::AttachClient(attrs, force) + ClientToServerMsg::AttachClient(attrs, force, options) => { + ServerInstruction::AttachClient(attrs, force, options) } _ => unreachable!(), } @@ -226,7 +226,7 @@ pub fn start_server(os_input: Box, socket_path: PathBuf) { .send_to_pty(PtyInstruction::NewTab) .unwrap(); } - ServerInstruction::AttachClient(attrs, _) => { + ServerInstruction::AttachClient(attrs, _, options) => { *session_state.write().unwrap() = SessionState::Attached; let rlock = session_data.read().unwrap(); let session_data = rlock.as_ref().unwrap(); @@ -234,8 +234,9 @@ pub fn start_server(os_input: Box, socket_path: PathBuf) { .senders .send_to_screen(ScreenInstruction::TerminalResize(attrs.position_and_size)) .unwrap(); + let default_mode = options.default_mode.unwrap_or_default(); let mode_info = - get_mode_info(InputMode::Normal, attrs.palette, session_data.capabilities); + get_mode_info(default_mode, attrs.palette, session_data.capabilities); session_data .senders .send_to_screen(ScreenInstruction::ChangeMode(mode_info.clone())) diff --git a/zellij-server/src/os_input_output.rs b/zellij-server/src/os_input_output.rs index 4cda73ed..a104dda2 100644 --- a/zellij-server/src/os_input_output.rs +++ b/zellij-server/src/os_input_output.rs @@ -41,7 +41,13 @@ pub(crate) fn set_terminal_size_using_fd(fd: RawFd, columns: u16, rows: u16) { ws_xpixel: 0, ws_ypixel: 0, }; - unsafe { ioctl(fd, TIOCSWINSZ, &winsize) }; + // TIOCGWINSZ is an u32, but the second argument to ioctl is u64 on + // some platforms. When checked on Linux, clippy will complain about + // useless conversion. + #[allow(clippy::useless_conversion)] + unsafe { + ioctl(fd, TIOCSWINSZ.into(), &winsize) + }; } /// Handle some signals for the child process. This will loop until the child diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index baac1e9c..285f333c 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -238,7 +238,7 @@ pub(crate) fn route_thread_main( to_server.send(instruction.into()).unwrap(); } } - ClientToServerMsg::AttachClient(_, force) => { + ClientToServerMsg::AttachClient(_, force, _) => { if *session_state.read().unwrap() == SessionState::Attached && !force { os_input.send_to_temp_client(ServerToClientMsg::Exit(ExitReason::CannotAttach)); } else { diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 068037ee..48be44bf 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -405,6 +405,7 @@ pub(crate) fn screen_thread_main( session_state: Arc>, ) { let capabilities = config_options.simplified_ui; + let default_mode = config_options.default_mode.unwrap_or_default(); let mut screen = Screen::new( bus, @@ -415,9 +416,10 @@ pub(crate) fn screen_thread_main( capabilities: PluginCapabilities { arrow_fonts: capabilities, }, + mode: default_mode, ..ModeInfo::default() }, - InputMode::Normal, + default_mode, session_state, ); loop { diff --git a/zellij-tile/src/data.rs b/zellij-tile/src/data.rs index 38b20dcd..2111d9aa 100644 --- a/zellij-tile/src/data.rs +++ b/zellij-tile/src/data.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use std::str::FromStr; use strum_macros::{EnumDiscriminants, EnumIter, EnumString, ToString}; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -92,6 +93,23 @@ impl Default for PaletteColor { } } +impl FromStr for InputMode { + type Err = Box; + + fn from_str(s: &str) -> Result { + match s { + "normal" => Ok(InputMode::Normal), + "resize" => Ok(InputMode::Resize), + "locked" => Ok(InputMode::Locked), + "pane" => Ok(InputMode::Pane), + "tab" => Ok(InputMode::Tab), + "scroll" => Ok(InputMode::Scroll), + "renametab" => Ok(InputMode::RenameTab), + e => Err(e.to_string().into()), + } + } +} + #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] pub enum PaletteSource { Default, diff --git a/zellij-utils/src/input/options.rs b/zellij-utils/src/input/options.rs index c6c002b6..64256976 100644 --- a/zellij-utils/src/input/options.rs +++ b/zellij-utils/src/input/options.rs @@ -2,6 +2,7 @@ use crate::cli::Command; use serde::{Deserialize, Serialize}; use structopt::StructOpt; +use zellij_tile::data::InputMode; #[derive(Clone, Default, Debug, PartialEq, Deserialize, Serialize, StructOpt)] /// Options that can be set either through the config file, @@ -14,6 +15,9 @@ pub struct Options { /// Set the default theme #[structopt(long)] pub theme: Option, + /// Set the default mode + #[structopt(long)] + pub default_mode: Option, } impl Options { @@ -35,11 +39,20 @@ impl Options { self.simplified_ui }; - let theme = None; + let default_mode = match other.default_mode { + None => self.default_mode, + other => other, + }; + + let theme = match other.theme { + None => self.theme.clone(), + other => other, + }; Options { simplified_ui, theme, + default_mode, } } diff --git a/zellij-utils/src/ipc.rs b/zellij-utils/src/ipc.rs index a160b782..3d75f8a7 100644 --- a/zellij-utils/src/ipc.rs +++ b/zellij-utils/src/ipc.rs @@ -57,7 +57,7 @@ pub enum ClientToServerMsg { DisconnectFromSession,*/ TerminalResize(PositionAndSize), NewClient(ClientAttributes, Box, Box), - AttachClient(ClientAttributes, bool), + AttachClient(ClientAttributes, bool, Options), Action(Action), ClientExited, }