feat(ui): laying the groundwork for a new resize algorithm

This commit is contained in:
Brooks Rady 2021-06-03 13:15:56 +01:00 committed by GitHub
commit c65987a285
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 552 additions and 285 deletions

7
Cargo.lock generated
View file

@ -271,6 +271,12 @@ version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
[[package]]
name = "cassowary"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "cc"
version = "1.0.67"
@ -2345,6 +2351,7 @@ version = "0.13.0"
dependencies = [
"ansi_term 0.12.1",
"async-trait",
"cassowary",
"daemonize",
"insta",
"serde_json",

View file

@ -57,3 +57,4 @@ assets = [
[features]
disable_automatic_asset_installation = []
parametric_resize_beta = []

View file

@ -135,7 +135,7 @@ impl ZellijPlugin for State {
fn load(&mut self) {
set_selectable(false);
set_invisible_borders(true);
set_max_height(2);
set_fixed_height(2);
subscribe(&[EventType::ModeUpdate]);
}

View file

@ -26,7 +26,7 @@ impl ZellijPlugin for State {
fn load(&mut self) {
set_selectable(false);
set_invisible_borders(true);
set_max_height(1);
set_fixed_height(1);
subscribe(&[EventType::TabUpdate, EventType::ModeUpdate]);
}
@ -57,7 +57,6 @@ impl ZellijPlugin for State {
let tab = tab_style(
tabname,
t.active,
t.position,
t.is_sync_panes_active,
self.mode_info.palette,
self.mode_info.capabilities,

View file

@ -40,7 +40,6 @@ pub fn non_active_tab(text: String, palette: Palette, separator: &str) -> LinePa
pub fn tab_style(
text: String,
is_active_tab: bool,
position: usize,
is_sync_panes_active: bool,
palette: Palette,
capabilities: PluginCapabilities,

View file

@ -20,7 +20,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test]
pub fn starts_with_one_terminal() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -48,7 +48,7 @@ pub fn starts_with_one_terminal() {
#[test]
pub fn split_terminals_vertically() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -76,7 +76,7 @@ pub fn split_terminals_vertically() {
#[test]
pub fn split_terminals_horizontally() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -105,7 +105,7 @@ pub fn split_terminals_horizontally() {
pub fn split_largest_terminal() {
// this finds the largest pane and splits along its longest edge (vertically or horizontally)
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -139,7 +139,7 @@ pub fn split_largest_terminal() {
#[test]
pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() {
let fake_win_size = PositionAndSize {
columns: 8,
cols: 8,
rows: 20,
x: 0,
y: 0,
@ -167,7 +167,7 @@ pub fn cannot_split_terminals_vertically_when_active_terminal_is_too_small() {
#[test]
pub fn cannot_split_terminals_horizontally_when_active_terminal_is_too_small() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 4,
x: 0,
y: 0,
@ -195,7 +195,7 @@ pub fn cannot_split_terminals_horizontally_when_active_terminal_is_too_small() {
#[test]
pub fn cannot_split_largest_terminal_when_there_is_no_room() {
let fake_win_size = PositionAndSize {
columns: 8,
cols: 8,
rows: 4,
x: 0,
y: 0,
@ -223,7 +223,7 @@ pub fn cannot_split_largest_terminal_when_there_is_no_room() {
#[test]
pub fn scrolling_up_inside_a_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -259,7 +259,7 @@ pub fn scrolling_up_inside_a_pane() {
#[test]
pub fn scrolling_down_inside_a_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -297,7 +297,7 @@ pub fn scrolling_down_inside_a_pane() {
#[test]
pub fn scrolling_page_up_inside_a_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -332,7 +332,7 @@ pub fn scrolling_page_up_inside_a_pane() {
#[test]
pub fn scrolling_page_down_inside_a_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -372,7 +372,7 @@ pub fn max_panes() {
// with the --max-panes option, we only allow a certain amount of panes on screen
// simultaneously, new panes beyond this limit will close older panes on screen
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -409,7 +409,7 @@ pub fn max_panes() {
#[test]
pub fn toggle_focused_pane_fullscreen() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -452,7 +452,7 @@ pub fn bracketed_paste() {
// since it's inside a bracketed paste block, while the "QUIT" command is, since it is already
// past the block
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,

View file

@ -28,7 +28,7 @@ pub fn close_pane_with_another_pane_above_it() {
// └───────────┘ └───────────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -70,7 +70,7 @@ pub fn close_pane_with_another_pane_below_it() {
// └───────────┘ └───────────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -111,7 +111,7 @@ pub fn close_pane_with_another_pane_to_the_left() {
// └─────┴─────┘ └──────────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -151,7 +151,7 @@ pub fn close_pane_with_another_pane_to_the_right() {
// └─────┴─────┘ └──────────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -194,7 +194,7 @@ pub fn close_pane_with_multiple_panes_above_it() {
// └───────────┘ └─────┴─────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -240,7 +240,7 @@ pub fn close_pane_with_multiple_panes_below_it() {
// └─────┴─────┘ └─────┴─────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -284,7 +284,7 @@ pub fn close_pane_with_multiple_panes_to_the_left() {
// └─────┴─────┘ └──────────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -330,7 +330,7 @@ pub fn close_pane_with_multiple_panes_to_the_right() {
// └─────┴─────┘ └──────────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -374,7 +374,7 @@ pub fn close_pane_with_multiple_panes_above_it_away_from_screen_edges() {
// └───┴───────┴───┘ └───┴───┴───┴───┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -441,7 +441,7 @@ pub fn close_pane_with_multiple_panes_below_it_away_from_screen_edges() {
// └───┴───┴───┴───┘ └───┴───┴───┴───┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -506,7 +506,7 @@ pub fn close_pane_with_multiple_panes_to_the_left_away_from_screen_edges() {
// └────┴──────┘ └────┴──────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 30,
x: 0,
y: 0,
@ -571,7 +571,7 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() {
// └────┴──────┘ └────┴──────┘
// █ == pane being closed
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 30,
x: 0,
y: 0,
@ -626,7 +626,7 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() {
#[test]
pub fn closing_last_pane_exits_app() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,

View file

@ -27,14 +27,14 @@ use zellij_utils::input::config::Config;
fn get_fake_os_input(fake_win_size: &PositionAndSize, fixture_name: &str) -> FakeInputOutput {
let mut tty_inputs = HashMap::new();
let fixture_bytes = Bytes::from_file_in_fixtures(&fixture_name);
tty_inputs.insert(fake_win_size.columns as u16, fixture_bytes);
tty_inputs.insert(fake_win_size.cols as u16, fixture_bytes);
FakeInputOutput::new(fake_win_size.clone()).with_tty_inputs(tty_inputs)
}
#[test]
pub fn run_bandwhich_from_fish_shell() {
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -64,7 +64,7 @@ pub fn run_bandwhich_from_fish_shell() {
#[test]
pub fn fish_tab_completion_options() {
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -98,7 +98,7 @@ pub fn fish_select_tab_completion_options() {
// this is not clearly seen in the snapshot because it does not include styles,
// but we can see the command line change and the cursor staying in place
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -136,7 +136,7 @@ pub fn vim_scroll_region_down() {
// file
// experience appear to the user
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -171,7 +171,7 @@ pub fn vim_ctrl_d() {
// end of the scroll region
// vim makes sure to fill these empty lines with the rest of the file
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -205,7 +205,7 @@ pub fn vim_ctrl_u() {
// this causes the effect of scrolling up X lines (vim replaces the lines with the ones in the
// file above the current content)
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -234,7 +234,7 @@ pub fn vim_ctrl_u() {
#[test]
pub fn htop() {
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -263,7 +263,7 @@ pub fn htop() {
#[test]
pub fn htop_scrolling() {
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -292,7 +292,7 @@ pub fn htop_scrolling() {
#[test]
pub fn htop_right_scrolling() {
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -329,7 +329,7 @@ pub fn vim_overwrite() {
// * confirm you would like to change the file by pressing 'y' and then ENTER
// * if everything looks fine, this test passed :)
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -361,7 +361,7 @@ pub fn clear_scroll_region() {
// this means that when vim exits, we get back the previous scroll
// buffer
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -390,7 +390,7 @@ pub fn clear_scroll_region() {
#[test]
pub fn display_tab_characters_properly() {
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -419,7 +419,7 @@ pub fn display_tab_characters_properly() {
#[test]
pub fn neovim_insert_mode() {
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -450,7 +450,7 @@ pub fn bash_cursor_linewrap() {
// this test makes sure that when we enter a command that is beyond the screen border, that it
// immediately goes down one line
let fake_win_size = PositionAndSize {
columns: 116,
cols: 116,
rows: 28,
x: 0,
y: 0,
@ -481,7 +481,7 @@ pub fn fish_paste_multiline() {
// here we paste a multiline command in fish shell, making sure we support it
// going up and changing the colors of our line-wrapped pasted text
let fake_win_size = PositionAndSize {
columns: 149,
cols: 149,
rows: 28,
x: 0,
y: 0,
@ -510,7 +510,7 @@ pub fn fish_paste_multiline() {
#[test]
pub fn git_log() {
let fake_win_size = PositionAndSize {
columns: 149,
cols: 149,
rows: 28,
x: 0,
y: 0,
@ -541,7 +541,7 @@ pub fn git_diff_scrollup() {
// this tests makes sure that when we have a git diff that exceeds the screen size
// we are able to scroll up
let fake_win_size = PositionAndSize {
columns: 149,
cols: 149,
rows: 28,
x: 0,
y: 0,
@ -570,7 +570,7 @@ pub fn git_diff_scrollup() {
#[test]
pub fn emacs_longbuf() {
let fake_win_size = PositionAndSize {
columns: 284,
cols: 284,
rows: 60,
x: 0,
y: 0,
@ -599,7 +599,7 @@ pub fn emacs_longbuf() {
#[test]
pub fn top_and_quit() {
let fake_win_size = PositionAndSize {
columns: 235,
cols: 235,
rows: 56,
x: 0,
y: 0,
@ -634,7 +634,7 @@ pub fn exa_plus_omf_theme() {
// over existing on-screen content without deleting it, so we must
// convert it to spaces
let fake_win_size = PositionAndSize {
columns: 235,
cols: 235,
rows: 56,
x: 0,
y: 0,

View file

@ -16,7 +16,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test]
pub fn accepts_basic_layout() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,

View file

@ -19,7 +19,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test]
pub fn move_focus_down() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -54,7 +54,7 @@ pub fn move_focus_down() {
#[test]
pub fn move_focus_down_to_the_most_recently_used_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,

View file

@ -20,7 +20,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test]
pub fn move_focus_left() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -54,7 +54,7 @@ pub fn move_focus_left() {
#[test]
pub fn move_focus_left_to_the_most_recently_used_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -92,7 +92,7 @@ pub fn move_focus_left_to_the_most_recently_used_pane() {
#[test]
pub fn move_focus_left_changes_tab() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,

View file

@ -20,7 +20,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test]
pub fn move_focus_right() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -55,7 +55,7 @@ pub fn move_focus_right() {
#[test]
pub fn move_focus_right_to_the_most_recently_used_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -92,7 +92,7 @@ pub fn move_focus_right_to_the_most_recently_used_pane() {
#[test]
pub fn move_focus_right_changes_tab() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,

View file

@ -19,7 +19,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test]
pub fn move_focus_up() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -53,7 +53,7 @@ pub fn move_focus_up() {
#[test]
pub fn move_focus_up_to_the_most_recently_used_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,

View file

@ -29,7 +29,7 @@ pub fn resize_down_with_pane_above() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -73,7 +73,7 @@ pub fn resize_down_with_pane_below() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -122,7 +122,7 @@ pub fn resize_down_with_panes_above_and_below() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 25,
x: 0,
y: 0,
@ -169,7 +169,7 @@ pub fn resize_down_with_multiple_panes_above() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -219,7 +219,7 @@ pub fn resize_down_with_panes_above_aligned_left_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -271,7 +271,7 @@ pub fn resize_down_with_panes_below_aligned_left_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -322,7 +322,7 @@ pub fn resize_down_with_panes_above_aligned_right_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -371,7 +371,7 @@ pub fn resize_down_with_panes_below_aligned_right_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -421,7 +421,7 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_current_pane() {
// └───┴───┴───┘ └───┴───┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -475,7 +475,7 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_current_pane() {
// └───┴───┴───┘ └───┴───┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -531,7 +531,7 @@ pub fn resize_down_with_panes_above_aligned_left_and_right_with_panes_to_the_lef
// └─┴─┴───┴─┴─┘ └─┴─┴───┴─┴─┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 40,
x: 0,
y: 0,
@ -605,7 +605,7 @@ pub fn resize_down_with_panes_below_aligned_left_and_right_with_to_the_left_and_
// └─┴───────┴─┘ └─┴───────┴─┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 40,
x: 0,
y: 0,
@ -678,7 +678,7 @@ pub fn cannot_resize_down_when_pane_below_is_at_minimum_height() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 7,
x: 0,
y: 0,

View file

@ -25,7 +25,7 @@ pub fn resize_left_with_pane_to_the_left() {
// └─────┴─────┘ └───┴───────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -67,7 +67,7 @@ pub fn resize_left_with_pane_to_the_right() {
// └─────┴─────┘ └───┴───────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -110,7 +110,7 @@ pub fn resize_left_with_panes_to_the_left_and_right() {
// └─────┴─────┴─────┘ └─────┴───┴───────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -155,7 +155,7 @@ pub fn resize_left_with_multiple_panes_to_the_left() {
// └─────┴─────┘ └───┴───────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -203,7 +203,7 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_with_current_pane() {
// └─────┴─────┘ └───┴───────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -253,7 +253,7 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_with_current_pane() {
// └─────┴─────┘ └───┴───────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -300,7 +300,7 @@ pub fn resize_left_with_panes_to_the_left_aligned_bottom_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -349,7 +349,7 @@ pub fn resize_left_with_panes_to_the_right_aligned_bottom_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -399,7 +399,7 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_current_pa
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -453,7 +453,7 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_current_p
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -509,7 +509,7 @@ pub fn resize_left_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abov
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 40,
x: 0,
y: 0,
@ -583,7 +583,7 @@ pub fn resize_left_with_panes_to_the_right_aligned_top_and_bottom_with_panes_abo
// █ == focused pane
let fake_win_size = PositionAndSize {
// TODO: combine with above
columns: 121,
cols: 121,
rows: 40,
x: 0,
y: 0,
@ -655,7 +655,7 @@ pub fn cannot_resize_left_when_pane_to_the_left_is_at_minimum_width() {
// └─┴─┘ └─┴─┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 9,
cols: 9,
rows: 20,
x: 0,
y: 0,

View file

@ -25,7 +25,7 @@ pub fn resize_right_with_pane_to_the_left() {
// └─────┴─────┘ └───────┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -67,7 +67,7 @@ pub fn resize_right_with_pane_to_the_right() {
// └─────┴─────┘ └───────┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -110,7 +110,7 @@ pub fn resize_right_with_panes_to_the_left_and_right() {
// └─────┴─────┴─────┘ └─────┴───────┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -155,7 +155,7 @@ pub fn resize_right_with_multiple_panes_to_the_left() {
// └─────┴─────┘ └───────┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -203,7 +203,7 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_with_current_pane() {
// └─────┴─────┘ └───────┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -253,7 +253,7 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_with_current_pane() {
// └─────┴─────┘ └───────┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -300,7 +300,7 @@ pub fn resize_right_with_panes_to_the_left_aligned_bottom_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -349,7 +349,7 @@ pub fn resize_right_with_panes_to_the_right_aligned_bottom_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -399,7 +399,7 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_current_p
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -453,7 +453,7 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_current_
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -509,7 +509,7 @@ pub fn resize_right_with_panes_to_the_left_aligned_top_and_bottom_with_panes_abo
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 40,
x: 0,
y: 0,
@ -582,7 +582,7 @@ pub fn resize_right_with_panes_to_the_right_aligned_top_and_bottom_with_panes_ab
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 40,
x: 0,
y: 0,
@ -654,7 +654,7 @@ pub fn cannot_resize_right_when_pane_to_the_left_is_at_minimum_width() {
// └─┴─┘ └─┴─┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 9,
cols: 9,
rows: 20,
x: 0,
y: 0,

View file

@ -27,7 +27,7 @@ pub fn resize_up_with_pane_above() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -71,7 +71,7 @@ pub fn resize_up_with_pane_below() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -119,7 +119,7 @@ pub fn resize_up_with_panes_above_and_below() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -165,7 +165,7 @@ pub fn resize_up_with_multiple_panes_above() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -213,7 +213,7 @@ pub fn resize_up_with_panes_above_aligned_left_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -265,7 +265,7 @@ pub fn resize_up_with_panes_below_aligned_left_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -316,7 +316,7 @@ pub fn resize_up_with_panes_above_aligned_right_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -365,7 +365,7 @@ pub fn resize_up_with_panes_below_aligned_right_with_current_pane() {
// └─────┴─────┘ └─────┴─────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -415,7 +415,7 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_current_pane() {
// └───┴───┴───┘ └───┴───┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -469,7 +469,7 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_current_pane() {
// └───┴───┴───┘ └───┴───┴───┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -525,7 +525,7 @@ pub fn resize_up_with_panes_above_aligned_left_and_right_with_panes_to_the_left_
// └─┴─┴───┴─┴─┘ └─┴─┴───┴─┴─┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 40,
x: 0,
y: 0,
@ -599,7 +599,7 @@ pub fn resize_up_with_panes_below_aligned_left_and_right_with_to_the_left_and_ri
// └─┴───────┴─┘ └─┴───────┴─┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 40,
x: 0,
y: 0,
@ -672,7 +672,7 @@ pub fn cannot_resize_up_when_pane_above_is_at_minimum_height() {
// └───────────┘ └───────────┘
// █ == focused pane
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 7,
x: 0,
y: 0,

View file

@ -21,7 +21,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test]
pub fn open_new_tab() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -56,7 +56,7 @@ pub fn open_new_tab() {
#[test]
pub fn switch_to_prev_tab() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -92,7 +92,7 @@ pub fn switch_to_prev_tab() {
#[test]
pub fn switch_to_next_tab() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -128,7 +128,7 @@ pub fn switch_to_next_tab() {
#[test]
pub fn close_tab() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -164,7 +164,7 @@ pub fn close_tab() {
#[test]
pub fn close_last_pane_in_a_tab() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -201,7 +201,7 @@ pub fn close_last_pane_in_a_tab() {
#[test]
pub fn close_the_middle_tab() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -240,7 +240,7 @@ pub fn close_the_middle_tab() {
#[test]
pub fn close_the_tab_that_has_a_pane_in_fullscreen() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -284,7 +284,7 @@ pub fn close_the_tab_that_has_a_pane_in_fullscreen() {
#[test]
pub fn closing_last_tab_exits_the_app() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,

View file

@ -15,7 +15,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test]
pub fn window_width_decrease_with_one_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -24,7 +24,7 @@ pub fn window_width_decrease_with_one_pane() {
let mut fake_input_output = get_fake_os_input(&fake_win_size);
fake_input_output.add_terminal_input(&[&QUIT]);
fake_input_output.add_sigwinch_event(PositionAndSize {
columns: 90,
cols: 90,
rows: 20,
x: 0,
y: 0,
@ -51,7 +51,7 @@ pub fn window_width_decrease_with_one_pane() {
#[test]
pub fn window_width_increase_with_one_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -60,7 +60,7 @@ pub fn window_width_increase_with_one_pane() {
let mut fake_input_output = get_fake_os_input(&fake_win_size);
fake_input_output.add_terminal_input(&[&QUIT]);
fake_input_output.add_sigwinch_event(PositionAndSize {
columns: 141,
cols: 141,
rows: 20,
x: 0,
y: 0,
@ -87,7 +87,7 @@ pub fn window_width_increase_with_one_pane() {
#[test]
pub fn window_height_increase_with_one_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -96,7 +96,7 @@ pub fn window_height_increase_with_one_pane() {
let mut fake_input_output = get_fake_os_input(&fake_win_size);
fake_input_output.add_terminal_input(&[&QUIT]);
fake_input_output.add_sigwinch_event(PositionAndSize {
columns: 121,
cols: 121,
rows: 30,
x: 0,
y: 0,
@ -123,7 +123,7 @@ pub fn window_height_increase_with_one_pane() {
#[test]
pub fn window_width_and_height_decrease_with_one_pane() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -132,7 +132,7 @@ pub fn window_width_and_height_decrease_with_one_pane() {
let mut fake_input_output = get_fake_os_input(&fake_win_size);
fake_input_output.add_terminal_input(&[&QUIT]);
fake_input_output.add_sigwinch_event(PositionAndSize {
columns: 90,
cols: 90,
rows: 10,
x: 0,
y: 0,

View file

@ -19,7 +19,7 @@ fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
#[test]
pub fn adding_new_terminal_in_fullscreen() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,
@ -54,7 +54,7 @@ pub fn adding_new_terminal_in_fullscreen() {
#[test]
pub fn move_focus_is_disabled_in_fullscreen() {
let fake_win_size = PositionAndSize {
columns: 121,
cols: 121,
rows: 20,
x: 0,
y: 0,

View file

@ -16,6 +16,7 @@ serde_json = "1.0"
unicode-width = "0.1.8"
wasmer = "1.0.0"
wasmer-wasi = "1.0.0"
cassowary = "0.3.0"
zellij-utils = { path = "../zellij-utils/", version = "0.13.0" }
[dev-dependencies]

View file

@ -113,6 +113,8 @@ pub fn start_server(os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
daemonize::Daemonize::new()
.working_directory(std::env::current_dir().unwrap())
.umask(0o077)
// FIXME: My cherished `dbg!` was broken, so this is a hack to bring it back
//.stderr(std::fs::File::create("dbg.log").unwrap())
.start()
.expect("could not daemonize the server process");

View file

@ -16,8 +16,6 @@ pub(crate) struct PluginPane {
pub position_and_size: PositionAndSize,
pub position_and_size_override: Option<PositionAndSize>,
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
pub max_height: Option<usize>,
pub max_width: Option<usize>,
pub active_at: Instant,
}
@ -35,8 +33,6 @@ impl PluginPane {
position_and_size,
position_and_size_override: None,
send_plugin_instructions,
max_height: None,
max_width: None,
active_at: Instant::now(),
}
}
@ -64,7 +60,7 @@ impl Pane for PluginPane {
fn columns(&self) -> usize {
self.position_and_size_override
.unwrap_or(self.position_and_size)
.columns
.cols
}
fn reset_size_and_position_override(&mut self) {
self.position_and_size_override = None;
@ -80,7 +76,7 @@ impl Pane for PluginPane {
x,
y,
rows: size.rows,
columns: size.columns,
cols: size.cols,
..Default::default()
};
self.position_and_size_override = Some(position_and_size_override);
@ -95,7 +91,9 @@ impl Pane for PluginPane {
fn adjust_input_to_terminal(&self, _input_bytes: Vec<u8>) -> Vec<u8> {
unimplemented!() // FIXME: Shouldn't need this implmented?
}
fn position_and_size(&self) -> PositionAndSize {
self.position_and_size
}
fn position_and_size_override(&self) -> Option<PositionAndSize> {
self.position_and_size_override
}
@ -114,11 +112,13 @@ impl Pane for PluginPane {
fn set_invisible_borders(&mut self, invisible_borders: bool) {
self.invisible_borders = invisible_borders;
}
fn set_max_height(&mut self, max_height: usize) {
self.max_height = Some(max_height);
fn set_fixed_height(&mut self, fixed_height: usize) {
self.position_and_size.rows = fixed_height;
self.position_and_size.rows_fixed = true;
}
fn set_max_width(&mut self, max_width: usize) {
self.max_width = Some(max_width);
fn set_fixed_width(&mut self, fixed_width: usize) {
self.position_and_size.cols = fixed_width;
self.position_and_size.cols_fixed = true;
}
fn render(&mut self) -> Option<String> {
// if self.should_render {
@ -167,20 +167,20 @@ impl Pane for PluginPane {
}
fn reduce_width_right(&mut self, count: usize) {
self.position_and_size.x += count;
self.position_and_size.columns -= count;
self.position_and_size.cols -= count;
self.should_render = true;
}
fn reduce_width_left(&mut self, count: usize) {
self.position_and_size.columns -= count;
self.position_and_size.cols -= count;
self.should_render = true;
}
fn increase_width_left(&mut self, count: usize) {
self.position_and_size.x -= count;
self.position_and_size.columns += count;
self.position_and_size.cols += count;
self.should_render = true;
}
fn increase_width_right(&mut self, count: usize) {
self.position_and_size.columns += count;
self.position_and_size.cols += count;
self.should_render = true;
}
fn push_down(&mut self, count: usize) {
@ -204,11 +204,21 @@ impl Pane for PluginPane {
fn clear_scroll(&mut self) {
unimplemented!()
}
// FIXME: This need to be reevaluated and deleted if possible.
// `max` doesn't make sense when things are fixed...
fn max_height(&self) -> Option<usize> {
self.max_height
if self.position_and_size.rows_fixed {
Some(self.position_and_size.rows)
} else {
None
}
}
fn max_width(&self) -> Option<usize> {
self.max_width
if self.position_and_size.cols_fixed {
Some(self.position_and_size.cols)
} else {
None
}
}
fn invisible_borders(&self) -> bool {
self.invisible_borders

View file

@ -27,8 +27,6 @@ pub struct TerminalPane {
pub selectable: bool,
pub position_and_size: PositionAndSize,
pub position_and_size_override: Option<PositionAndSize>,
pub max_height: Option<usize>,
pub max_width: Option<usize>,
pub active_at: Instant,
pub colors: Palette,
vte_parser: vte::Parser,
@ -52,8 +50,7 @@ impl Pane for TerminalPane {
self.reflow_lines();
}
fn change_pos_and_size(&mut self, position_and_size: &PositionAndSize) {
self.position_and_size.columns = position_and_size.columns;
self.position_and_size.rows = position_and_size.rows;
self.position_and_size = *position_and_size;
self.reflow_lines();
}
fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize) {
@ -61,7 +58,7 @@ impl Pane for TerminalPane {
x,
y,
rows: size.rows,
columns: size.columns,
cols: size.cols,
..Default::default()
};
self.position_and_size_override = Some(position_and_size_override);
@ -119,7 +116,9 @@ impl Pane for TerminalPane {
};
input_bytes
}
fn position_and_size(&self) -> PositionAndSize {
self.position_and_size
}
fn position_and_size_override(&self) -> Option<PositionAndSize> {
self.position_and_size_override
}
@ -138,21 +137,17 @@ impl Pane for TerminalPane {
fn set_selectable(&mut self, selectable: bool) {
self.selectable = selectable;
}
fn set_max_height(&mut self, max_height: usize) {
self.max_height = Some(max_height);
fn set_fixed_height(&mut self, fixed_height: usize) {
self.position_and_size.rows = fixed_height;
self.position_and_size.rows_fixed = true;
}
fn set_max_width(&mut self, max_width: usize) {
self.max_width = Some(max_width);
fn set_fixed_width(&mut self, fixed_width: usize) {
self.position_and_size.cols = fixed_width;
self.position_and_size.cols_fixed = true;
}
fn set_invisible_borders(&mut self, _invisible_borders: bool) {
unimplemented!();
}
fn max_height(&self) -> Option<usize> {
self.max_height
}
fn max_width(&self) -> Option<usize> {
self.max_width
}
fn render(&mut self) -> Option<String> {
if self.should_render() {
let mut vte_output = String::new();
@ -229,20 +224,20 @@ impl Pane for TerminalPane {
}
fn reduce_width_right(&mut self, count: usize) {
self.position_and_size.x += count;
self.position_and_size.columns -= count;
self.position_and_size.cols -= count;
self.reflow_lines();
}
fn reduce_width_left(&mut self, count: usize) {
self.position_and_size.columns -= count;
self.position_and_size.cols -= count;
self.reflow_lines();
}
fn increase_width_left(&mut self, count: usize) {
self.position_and_size.x -= count;
self.position_and_size.columns += count;
self.position_and_size.cols += count;
self.reflow_lines();
}
fn increase_width_right(&mut self, count: usize) {
self.position_and_size.columns += count;
self.position_and_size.cols += count;
self.reflow_lines();
}
fn push_down(&mut self, count: usize) {
@ -294,15 +289,13 @@ impl Pane for TerminalPane {
impl TerminalPane {
pub fn new(pid: RawFd, position_and_size: PositionAndSize, palette: Palette) -> TerminalPane {
let grid = Grid::new(position_and_size.rows, position_and_size.columns, palette);
let grid = Grid::new(position_and_size.rows, position_and_size.cols, palette);
TerminalPane {
pid,
grid,
selectable: true,
position_and_size,
position_and_size_override: None,
max_height: None,
max_width: None,
vte_parser: vte::Parser::new(),
active_at: Instant::now(),
colors: palette,
@ -322,8 +315,8 @@ impl TerminalPane {
}
pub fn get_columns(&self) -> usize {
match &self.position_and_size_override.as_ref() {
Some(position_and_size_override) => position_and_size_override.columns,
None => self.position_and_size.columns as usize,
Some(position_and_size_override) => position_and_size_override.cols,
None => self.position_and_size.cols as usize,
}
}
pub fn get_rows(&self) -> usize {

View file

@ -55,7 +55,8 @@ pub(crate) enum ScreenInstruction {
CloseFocusedPane,
ToggleActiveTerminalFullscreen,
SetSelectable(PaneId, bool),
SetMaxHeight(PaneId, usize),
SetFixedHeight(PaneId, usize),
SetFixedWidth(PaneId, usize),
SetInvisibleBorders(PaneId, bool),
ClosePane(PaneId),
ApplyLayout(Layout, Vec<RawFd>),
@ -106,7 +107,8 @@ impl From<&ScreenInstruction> for ScreenContext {
}
ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable,
ScreenInstruction::SetInvisibleBorders(..) => ScreenContext::SetInvisibleBorders,
ScreenInstruction::SetMaxHeight(..) => ScreenContext::SetMaxHeight,
ScreenInstruction::SetFixedHeight(..) => ScreenContext::SetFixedHeight,
ScreenInstruction::SetFixedWidth(..) => ScreenContext::SetFixedWidth,
ScreenInstruction::ClosePane(_) => ScreenContext::ClosePane,
ScreenInstruction::ApplyLayout(..) => ScreenContext::ApplyLayout,
ScreenInstruction::NewTab(_) => ScreenContext::NewTab,
@ -574,11 +576,17 @@ pub(crate) fn screen_thread_main(
.unwrap()
.set_pane_selectable(id, selectable);
}
ScreenInstruction::SetMaxHeight(id, max_height) => {
ScreenInstruction::SetFixedHeight(id, fixed_height) => {
screen
.get_active_tab_mut()
.unwrap()
.set_pane_max_height(id, max_height);
.set_pane_fixed_height(id, fixed_height);
}
ScreenInstruction::SetFixedWidth(id, fixed_width) => {
screen
.get_active_tab_mut()
.unwrap()
.set_pane_fixed_width(id, fixed_width);
}
ScreenInstruction::SetInvisibleBorders(id, invisible_borders) => {
screen

View file

@ -3,12 +3,16 @@
use zellij_utils::{serde, zellij_tile};
#[cfg(not(feature = "parametric_resize_beta"))]
use crate::ui::pane_resizer::PaneResizer;
#[cfg(feature = "parametric_resize_beta")]
use crate::ui::pane_resizer_beta::PaneResizer;
use crate::{
os_input_output::ServerOsApi,
panes::{PaneId, PluginPane, TerminalPane},
pty::{PtyInstruction, VteBytes},
thread_bus::ThreadSenders,
ui::{boundaries::Boundaries, layout::Layout, pane_resizer::PaneResizer},
ui::{boundaries::Boundaries, layout::Layout},
wasm_vm::PluginInstruction,
ServerInstruction, SessionState,
};
@ -33,16 +37,16 @@ const MIN_TERMINAL_WIDTH: usize = 4;
type BorderAndPaneIds = (usize, Vec<PaneId>);
fn split_vertically_with_gap(rect: &PositionAndSize) -> (PositionAndSize, PositionAndSize) {
let width_of_each_half = (rect.columns - 1) / 2;
let width_of_each_half = (rect.cols - 1) / 2;
let mut first_rect = *rect;
let mut second_rect = *rect;
if rect.columns % 2 == 0 {
first_rect.columns = width_of_each_half + 1;
if rect.cols % 2 == 0 {
first_rect.cols = width_of_each_half + 1;
} else {
first_rect.columns = width_of_each_half;
first_rect.cols = width_of_each_half;
}
second_rect.x = first_rect.x + first_rect.columns + 1;
second_rect.columns = width_of_each_half;
second_rect.x = first_rect.x + first_rect.cols + 1;
second_rect.cols = width_of_each_half;
(first_rect, second_rect)
}
@ -104,15 +108,15 @@ pub trait Pane {
fn handle_pty_bytes(&mut self, bytes: VteBytes);
fn cursor_coordinates(&self) -> Option<(usize, usize)>;
fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8>;
fn position_and_size(&self) -> PositionAndSize;
fn position_and_size_override(&self) -> Option<PositionAndSize>;
fn should_render(&self) -> bool;
fn set_should_render(&mut self, should_render: bool);
fn selectable(&self) -> bool;
fn set_selectable(&mut self, selectable: bool);
fn set_invisible_borders(&mut self, invisible_borders: bool);
fn set_max_height(&mut self, max_height: usize);
fn set_max_width(&mut self, max_width: usize);
fn set_fixed_height(&mut self, fixed_height: usize);
fn set_fixed_width(&mut self, fixed_width: usize);
fn render(&mut self) -> Option<String>;
fn pid(&self) -> PaneId;
fn reduce_height_down(&mut self, count: usize);
@ -178,15 +182,6 @@ pub trait Pane {
std::cmp::min(self.x() + self.columns(), other.x() + other.columns())
- std::cmp::max(self.x(), other.x())
}
fn position_and_size(&self) -> PositionAndSize {
PositionAndSize {
x: self.x(),
y: self.y(),
columns: self.columns(),
rows: self.rows(),
..Default::default()
}
}
fn can_increase_height_by(&self, increase_by: usize) -> bool {
self.max_height()
.map(|max_height| self.rows() + increase_by <= max_height)
@ -290,7 +285,7 @@ impl Tab {
x: 0,
y: 0,
rows: self.full_screen_ws.rows,
columns: self.full_screen_ws.columns,
cols: self.full_screen_ws.cols,
..Default::default()
};
self.panes_to_hide.clear();
@ -302,16 +297,10 @@ impl Tab {
match positions_and_size.next() {
Some((_, position_and_size)) => {
terminal_pane.reset_size_and_position_override();
if let Some(max_rows) = position_and_size.max_rows {
terminal_pane.set_max_height(max_rows);
}
if let Some(max_columns) = position_and_size.max_columns {
terminal_pane.set_max_width(max_columns);
}
terminal_pane.change_pos_and_size(&position_and_size);
self.os_api.set_terminal_size_using_fd(
*pid,
position_and_size.columns as u16,
position_and_size.cols as u16,
position_and_size.rows as u16,
);
}
@ -325,24 +314,18 @@ impl Tab {
}
let mut new_pids = new_pids.iter();
for (layout, position_and_size) in positions_and_size {
// Just a regular terminal
// A plugin pane
if let Some(plugin) = &layout.plugin {
let (pid_tx, pid_rx) = channel();
self.senders
.send_to_plugin(PluginInstruction::Load(pid_tx, plugin.clone()))
.unwrap();
let pid = pid_rx.recv().unwrap();
let mut new_plugin = PluginPane::new(
let new_plugin = PluginPane::new(
pid,
*position_and_size,
self.senders.to_plugin.as_ref().unwrap().clone(),
);
if let Some(max_rows) = position_and_size.max_rows {
new_plugin.set_max_height(max_rows);
}
if let Some(max_columns) = position_and_size.max_columns {
new_plugin.set_max_width(max_columns);
}
self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin));
// Send an initial mode update to the newly loaded plugin only!
self.senders
@ -422,7 +405,7 @@ impl Tab {
let terminal_to_split = self.panes.get_mut(&terminal_id_to_split).unwrap();
let terminal_ws = PositionAndSize {
rows: terminal_to_split.rows(),
columns: terminal_to_split.columns(),
cols: terminal_to_split.columns(),
x: terminal_to_split.x(),
y: terminal_to_split.y(),
..Default::default()
@ -435,7 +418,7 @@ impl Tab {
let new_terminal = TerminalPane::new(term_pid, bottom_winsize, self.colors);
self.os_api.set_terminal_size_using_fd(
new_terminal.pid,
bottom_winsize.columns as u16,
bottom_winsize.cols as u16,
bottom_winsize.rows as u16,
);
terminal_to_split.change_pos_and_size(&top_winsize);
@ -443,7 +426,7 @@ impl Tab {
if let PaneId::Terminal(terminal_id_to_split) = terminal_id_to_split {
self.os_api.set_terminal_size_using_fd(
terminal_id_to_split,
top_winsize.columns as u16,
top_winsize.cols as u16,
top_winsize.rows as u16,
);
}
@ -455,7 +438,7 @@ impl Tab {
let new_terminal = TerminalPane::new(term_pid, right_winsize, self.colors);
self.os_api.set_terminal_size_using_fd(
new_terminal.pid,
right_winsize.columns as u16,
right_winsize.cols as u16,
right_winsize.rows as u16,
);
terminal_to_split.change_pos_and_size(&left_winsize);
@ -463,7 +446,7 @@ impl Tab {
if let PaneId::Terminal(terminal_id_to_split) = terminal_id_to_split {
self.os_api.set_terminal_size_using_fd(
terminal_id_to_split,
left_winsize.columns as u16,
left_winsize.cols as u16,
left_winsize.rows as u16,
);
}
@ -503,7 +486,7 @@ impl Tab {
x: active_pane.x(),
y: active_pane.y(),
rows: active_pane.rows(),
columns: active_pane.columns(),
cols: active_pane.columns(),
..Default::default()
};
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
@ -513,7 +496,7 @@ impl Tab {
let new_terminal = TerminalPane::new(term_pid, bottom_winsize, self.colors);
self.os_api.set_terminal_size_using_fd(
new_terminal.pid,
bottom_winsize.columns as u16,
bottom_winsize.cols as u16,
bottom_winsize.rows as u16,
);
self.panes.insert(pid, Box::new(new_terminal));
@ -521,7 +504,7 @@ impl Tab {
if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
self.os_api.set_terminal_size_using_fd(
*active_terminal_pid,
top_winsize.columns as u16,
top_winsize.cols as u16,
top_winsize.rows as u16,
);
}
@ -560,7 +543,7 @@ impl Tab {
x: active_pane.x(),
y: active_pane.y(),
rows: active_pane.rows(),
columns: active_pane.columns(),
cols: active_pane.columns(),
..Default::default()
};
let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
@ -570,7 +553,7 @@ impl Tab {
let new_terminal = TerminalPane::new(term_pid, right_winsize, self.colors);
self.os_api.set_terminal_size_using_fd(
new_terminal.pid,
right_winsize.columns as u16,
right_winsize.cols as u16,
right_winsize.rows as u16,
);
self.panes.insert(pid, Box::new(new_terminal));
@ -578,7 +561,7 @@ impl Tab {
if let PaneId::Terminal(active_terminal_pid) = active_pane_id {
self.os_api.set_terminal_size_using_fd(
*active_terminal_pid,
left_winsize.columns as u16,
left_winsize.cols as u16,
left_winsize.rows as u16,
);
}
@ -740,7 +723,7 @@ impl Tab {
}
let mut output = String::new();
let mut boundaries = Boundaries::new(
self.full_screen_ws.columns as u16,
self.full_screen_ws.cols as u16,
self.full_screen_ws.rows as u16,
);
let hide_cursor = "\u{1b}[?25l";
@ -1151,7 +1134,7 @@ impl Tab {
}
}
// rightmost border aligned with a pane border above
let mut right_resize_border = self.full_screen_ws.columns;
let mut right_resize_border = self.full_screen_ws.cols;
for terminal in &terminals {
let left_terminal_boundary = terminal.x();
if terminal_borders_above
@ -1229,7 +1212,7 @@ impl Tab {
}
}
// leftmost border aligned with a pane border above
let mut right_resize_border = self.full_screen_ws.columns;
let mut right_resize_border = self.full_screen_ws.cols;
for terminal in &terminals {
let left_terminal_boundary = terminal.x();
if terminal_borders_below
@ -1571,7 +1554,7 @@ impl Tab {
return false;
}
let mut new_pos_and_size_for_pane = pane.position_and_size();
new_pos_and_size_for_pane.columns += increase_by;
new_pos_and_size_for_pane.cols += increase_by;
if let Some(panes_to_the_right) = self.pane_ids_directly_right_of(&pane_id) {
return panes_to_the_right.iter().all(|id| {
@ -1739,8 +1722,8 @@ impl Tab {
.resize(self.full_screen_ws, new_screen_size)
{
self.should_clear_display_before_rendering = true;
self.full_screen_ws.columns =
(self.full_screen_ws.columns as isize + column_difference) as usize;
self.full_screen_ws.cols =
(self.full_screen_ws.cols as isize + column_difference) as usize;
self.full_screen_ws.rows =
(self.full_screen_ws.rows as isize + row_difference) as usize;
};
@ -2132,9 +2115,14 @@ impl Tab {
pane.set_invisible_borders(invisible_borders);
}
}
pub fn set_pane_max_height(&mut self, id: PaneId, max_height: usize) {
pub fn set_pane_fixed_height(&mut self, id: PaneId, fixed_height: usize) {
if let Some(pane) = self.panes.get_mut(&id) {
pane.set_max_height(max_height);
pane.set_fixed_height(fixed_height);
}
}
pub fn set_pane_fixed_width(&mut self, id: PaneId, fixed_width: usize) {
if let Some(pane) = self.panes.get_mut(&id) {
pane.set_fixed_width(fixed_width);
}
}
pub fn close_pane(&mut self, id: PaneId) {

View file

@ -13,31 +13,27 @@ fn split_space_to_parts_vertically(
let mut split_parts = Vec::new();
let mut current_x_position = space_to_split.x;
let mut current_width = 0;
let max_width = space_to_split.columns - (sizes.len() - 1); // minus space for gaps
let max_width = space_to_split.cols - (sizes.len() - 1); // minus space for gaps
let mut parts_to_grow = Vec::new();
// First fit in the parameterized sizes
for size in sizes {
let (columns, max_columns) = match size {
let columns = match size {
Some(SplitSize::Percent(percent)) => {
((max_width as f32 * (percent as f32 / 100.0)) as usize, None)
(max_width as f32 * (percent as f32 / 100.0)) as usize
} // TODO: round properly
Some(SplitSize::Fixed(size)) => (size as usize, Some(size as usize)),
Some(SplitSize::Fixed(size)) => size as usize,
None => {
parts_to_grow.push(current_x_position);
(
1, // This is grown later on
None,
)
1 // This is grown later on
}
};
split_parts.push(PositionAndSize {
x: current_x_position,
y: space_to_split.y,
columns,
cols: columns,
rows: space_to_split.rows,
max_columns,
..Default::default()
});
current_width += columns;
@ -55,11 +51,11 @@ fn split_space_to_parts_vertically(
for (idx, part) in split_parts.iter_mut().enumerate() {
part.x = current_x_position;
if parts_to_grow.contains(&part.x) {
part.columns = new_columns;
part.cols = new_columns;
last_flexible_index = idx;
}
current_width += part.columns;
current_x_position += part.columns + 1; // 1 for gap
current_width += part.cols;
current_x_position += part.cols + 1; // 1 for gap
}
}
@ -67,7 +63,7 @@ fn split_space_to_parts_vertically(
// we have some extra space left, let's add it to the last flexible part
let extra = max_width - current_width;
let mut last_part = split_parts.get_mut(last_flexible_index).unwrap();
last_part.columns += extra;
last_part.cols += extra;
for part in (&mut split_parts[last_flexible_index + 1..]).iter_mut() {
part.x += extra;
}
@ -87,26 +83,21 @@ fn split_space_to_parts_horizontally(
let mut parts_to_grow = Vec::new();
for size in sizes {
let (rows, max_rows) = match size {
Some(SplitSize::Percent(percent)) => (
(max_height as f32 * (percent as f32 / 100.0)) as usize,
None,
), // TODO: round properly
Some(SplitSize::Fixed(size)) => (size as usize, Some(size as usize)),
let rows = match size {
Some(SplitSize::Percent(percent)) => {
(max_height as f32 * (percent as f32 / 100.0)) as usize
} // TODO: round properly
Some(SplitSize::Fixed(size)) => size as usize,
None => {
parts_to_grow.push(current_y_position);
(
1, // This is grown later on
None,
)
1 // This is grown later on
}
};
split_parts.push(PositionAndSize {
x: space_to_split.x,
y: current_y_position,
columns: space_to_split.columns,
cols: space_to_split.cols,
rows,
max_rows,
..Default::default()
});
current_height += rows;

View file

@ -1,3 +1,4 @@
pub mod boundaries;
pub mod layout;
pub mod pane_resizer;
pub mod pane_resizer_beta;

View file

@ -29,37 +29,35 @@ impl<'a> PaneResizer<'a> {
let mut successfully_resized = false;
let mut column_difference: isize = 0;
let mut row_difference: isize = 0;
match new_size.columns.cmp(&current_size.columns) {
match new_size.cols.cmp(&current_size.cols) {
Ordering::Greater => {
let increase_by = new_size.columns - current_size.columns;
let increase_by = new_size.cols - current_size.cols;
if let Some(panes_to_resize) = find_increasable_vertical_chain(
&self.panes,
increase_by,
current_size.columns,
current_size.cols,
current_size.rows,
) {
self.increase_panes_right_and_push_adjacents_right(
panes_to_resize,
increase_by,
);
column_difference = new_size.columns as isize - current_size.columns as isize;
current_size.columns =
(current_size.columns as isize + column_difference) as usize;
column_difference = new_size.cols as isize - current_size.cols as isize;
current_size.cols = (current_size.cols as isize + column_difference) as usize;
successfully_resized = true;
};
}
Ordering::Less => {
let reduce_by = current_size.columns - new_size.columns;
let reduce_by = current_size.cols - new_size.cols;
if let Some(panes_to_resize) = find_reducible_vertical_chain(
&self.panes,
reduce_by,
current_size.columns,
current_size.cols,
current_size.rows,
) {
self.reduce_panes_left_and_pull_adjacents_left(panes_to_resize, reduce_by);
column_difference = new_size.columns as isize - current_size.columns as isize;
current_size.columns =
(current_size.columns as isize + column_difference) as usize;
column_difference = new_size.cols as isize - current_size.cols as isize;
current_size.cols = (current_size.cols as isize + column_difference) as usize;
successfully_resized = true;
};
}
@ -71,7 +69,7 @@ impl<'a> PaneResizer<'a> {
if let Some(panes_to_resize) = find_increasable_horizontal_chain(
&self.panes,
increase_by,
current_size.columns,
current_size.cols,
current_size.rows,
) {
self.increase_panes_down_and_push_down_adjacents(panes_to_resize, increase_by);
@ -85,7 +83,7 @@ impl<'a> PaneResizer<'a> {
if let Some(panes_to_resize) = find_reducible_horizontal_chain(
&self.panes,
reduce_by,
current_size.columns,
current_size.cols,
current_size.rows,
) {
self.reduce_panes_up_and_pull_adjacents_up(panes_to_resize, reduce_by);

View file

@ -0,0 +1,248 @@
#![allow(dead_code)]
use crate::{os_input_output::ServerOsApi, panes::PaneId, tab::Pane};
use cassowary::{
strength::{REQUIRED, STRONG},
Constraint, Solver, Variable,
WeightedRelation::*,
};
use std::{
collections::{BTreeMap, HashSet},
ops::Not,
};
use zellij_utils::pane_size::PositionAndSize;
const GAP_SIZE: usize = 1; // Panes are separated by this number of rows / columns
pub struct PaneResizer<'a> {
panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
vars: BTreeMap<PaneId, (Variable, Variable)>,
solver: Solver,
os_api: &'a mut Box<dyn ServerOsApi>,
}
#[derive(Debug, Clone, Copy)]
enum Direction {
Horizontal,
Vertical,
}
impl Not for Direction {
type Output = Self;
fn not(self) -> Self::Output {
match self {
Direction::Horizontal => Direction::Vertical,
Direction::Vertical => Direction::Horizontal,
}
}
}
#[derive(Debug, Clone, Copy)]
struct Span {
pid: PaneId,
direction: Direction,
fixed: bool,
pos: usize,
size: usize,
pos_var: Variable,
size_var: Variable,
}
// TODO: currently there are some functions here duplicated with Tab
// all resizing functions should move here
// FIXME:
// 1. Rounding causes a loss of ratios, I need to store an internal f64 for
// each pane as well as the displayed usize and add custom rounding logic.
// 2. Vertical resizing doesn't seem to respect the space consumed by the tab
// and status bars?
// 3. A 2x2 layout and simultaneous vertical + horizontal resizing sometimes
// leads to unsolvable constraints? Maybe related to 2 (and possibly 1).
// I should sanity-check the `spans_in_boundary()` here!
impl<'a> PaneResizer<'a> {
pub fn new(
panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
os_api: &'a mut Box<dyn ServerOsApi>,
) -> Self {
let mut vars = BTreeMap::new();
for &k in panes.keys() {
vars.insert(k, (Variable::new(), Variable::new()));
}
PaneResizer {
panes,
vars,
solver: Solver::new(),
os_api,
}
}
pub fn resize(
&mut self,
current_size: PositionAndSize,
new_size: PositionAndSize,
) -> Option<(isize, isize)> {
let col_delta = new_size.cols as isize - current_size.cols as isize;
let row_delta = new_size.rows as isize - current_size.rows as isize;
if col_delta != 0 {
let spans = self.solve_direction(Direction::Horizontal, new_size.cols)?;
self.collapse_spans(&spans);
}
self.solver.reset();
if row_delta != 0 {
let spans = self.solve_direction(Direction::Vertical, new_size.rows)?;
self.collapse_spans(&spans);
}
Some((col_delta, row_delta))
}
fn solve_direction(&mut self, direction: Direction, space: usize) -> Option<Vec<Span>> {
let mut grid = Vec::new();
for boundary in self.grid_boundaries(direction) {
grid.push(self.spans_in_boundary(direction, boundary));
}
let constraints: Vec<_> = grid
.iter()
.flat_map(|s| constrain_spans(space, s))
.collect();
// FIXME: This line needs to be restored before merging!
//self.solver.add_constraints(&constraints).ok()?;
self.solver.add_constraints(&constraints).unwrap();
Some(grid.into_iter().flatten().collect())
}
fn grid_boundaries(&self, direction: Direction) -> Vec<(usize, usize)> {
// Select the spans running *perpendicular* to the direction of resize
let spans: Vec<Span> = self
.panes
.values()
.map(|p| self.get_span(!direction, p.as_ref()))
.collect();
let mut last_edge = 0;
let mut bounds = Vec::new();
loop {
let mut spans_on_edge: Vec<&Span> =
spans.iter().filter(|p| p.pos == last_edge).collect();
spans_on_edge.sort_unstable_by_key(|s| s.size);
if let Some(next) = spans_on_edge.first() {
let next_edge = last_edge + next.size;
bounds.push((last_edge, next_edge));
last_edge = next_edge + GAP_SIZE;
} else {
break;
}
}
bounds
}
fn spans_in_boundary(&self, direction: Direction, boundary: (usize, usize)) -> Vec<Span> {
let (start, end) = boundary;
let bwn = |v| start <= v && v < end;
let mut spans: Vec<_> = self
.panes
.values()
.filter(|p| {
let s = self.get_span(!direction, p.as_ref());
bwn(s.pos) || bwn(s.pos + s.size)
})
.map(|p| self.get_span(direction, p.as_ref()))
.collect();
spans.sort_unstable_by_key(|s| s.pos);
spans
}
fn get_span(&self, direction: Direction, pane: &dyn Pane) -> Span {
let pas = pane.position_and_size();
let (pos_var, size_var) = self.vars[&pane.pid()];
match direction {
Direction::Horizontal => Span {
pid: pane.pid(),
direction,
fixed: pas.cols_fixed,
pos: pas.x,
size: pas.cols,
pos_var,
size_var,
},
Direction::Vertical => Span {
pid: pane.pid(),
direction,
fixed: pas.rows_fixed,
pos: pas.y,
size: pas.rows,
pos_var,
size_var,
},
}
}
fn collapse_spans(&mut self, spans: &[Span]) {
for span in spans {
let solver = &self.solver; // Hand-holding the borrow-checker
let pane = self.panes.get_mut(&span.pid).unwrap();
let fetch_usize = |v| solver.get_value(v).round() as usize;
match span.direction {
Direction::Horizontal => pane.change_pos_and_size(&PositionAndSize {
x: fetch_usize(span.pos_var),
cols: fetch_usize(span.size_var),
..pane.position_and_size()
}),
Direction::Vertical => pane.change_pos_and_size(&PositionAndSize {
y: fetch_usize(span.pos_var),
rows: fetch_usize(span.size_var),
..pane.position_and_size()
}),
}
if let PaneId::Terminal(pid) = pane.pid() {
self.os_api.set_terminal_size_using_fd(
pid,
pane.columns() as u16,
pane.rows() as u16,
);
}
}
}
}
fn constrain_spans(space: usize, spans: &[Span]) -> HashSet<Constraint> {
let mut constraints = HashSet::new();
// The first span needs to start at 0
constraints.insert(spans[0].pos_var | EQ(REQUIRED) | 0.0);
// Calculating "flexible" space (space not consumed by fixed-size spans)
let gap_space = GAP_SIZE * (spans.len() - 1);
let old_flex_space = spans
.iter()
.fold(0, |a, s| if !s.fixed { a + s.size } else { a });
let new_flex_space = spans.iter().fold(
space - gap_space,
|a, s| if s.fixed { a - s.size } else { a },
);
// Keep spans stuck together
for pair in spans.windows(2) {
let (ls, rs) = (pair[0], pair[1]);
constraints
.insert((ls.pos_var + ls.size_var + GAP_SIZE as f64) | EQ(REQUIRED) | rs.pos_var);
}
// Try to maintain ratios and lock non-flexible sizes
for span in spans {
if span.fixed {
constraints.insert(span.size_var | EQ(REQUIRED) | span.size as f64);
} else {
let ratio = span.size as f64 / old_flex_space as f64;
constraints.insert((span.size_var / new_flex_space as f64) | EQ(STRONG) | ratio);
}
}
// The last pane needs to end at the end of the space
let last = spans.last().unwrap();
constraints.insert((last.pos_var + last.size_var) | EQ(REQUIRED) | space as f64);
constraints
}

View file

@ -158,7 +158,8 @@ pub(crate) fn zellij_exports(store: &Store, plugin_env: &PluginEnv) -> ImportObj
host_subscribe,
host_unsubscribe,
host_set_invisible_borders,
host_set_max_height,
host_set_fixed_height,
host_set_fixed_width,
host_set_selectable,
host_get_plugin_ids,
host_open_file,
@ -189,13 +190,24 @@ fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) {
.unwrap()
}
fn host_set_max_height(plugin_env: &PluginEnv, max_height: i32) {
let max_height = max_height as usize;
fn host_set_fixed_height(plugin_env: &PluginEnv, fixed_height: i32) {
let fixed_height = fixed_height as usize;
plugin_env
.senders
.send_to_screen(ScreenInstruction::SetMaxHeight(
.send_to_screen(ScreenInstruction::SetFixedHeight(
PaneId::Plugin(plugin_env.plugin_id),
max_height,
fixed_height,
))
.unwrap()
}
fn host_set_fixed_width(plugin_env: &PluginEnv, fixed_width: i32) {
let fixed_width = fixed_width as usize;
plugin_env
.senders
.send_to_screen(ScreenInstruction::SetFixedWidth(
PaneId::Plugin(plugin_env.plugin_id),
fixed_width,
))
.unwrap()
}

View file

@ -17,8 +17,12 @@ pub fn unsubscribe(event_types: &[EventType]) {
// Plugin Settings
pub fn set_max_height(max_height: i32) {
unsafe { host_set_max_height(max_height) };
pub fn set_fixed_height(fixed_height: i32) {
unsafe { host_set_fixed_height(fixed_height) };
}
pub fn set_fixed_width(fixed_width: i32) {
unsafe { host_set_fixed_width(fixed_width) };
}
pub fn set_selectable(selectable: bool) {
@ -64,7 +68,8 @@ pub fn object_to_stdout(object: &impl Serialize) {
extern "C" {
fn host_subscribe();
fn host_unsubscribe();
fn host_set_max_height(max_height: i32);
fn host_set_fixed_height(fixed_height: i32);
fn host_set_fixed_width(fixed_width: i32);
fn host_set_selectable(selectable: i32);
fn host_set_invisible_borders(invisible_borders: i32);
fn host_get_plugin_ids();

View file

@ -207,7 +207,8 @@ pub enum ScreenContext {
ToggleActiveTerminalFullscreen,
SetSelectable,
SetInvisibleBorders,
SetMaxHeight,
SetFixedHeight,
SetFixedWidth,
ClosePane,
ApplyLayout,
NewTab,

View file

@ -8,15 +8,18 @@ pub struct PositionAndSize {
pub x: usize,
pub y: usize,
pub rows: usize,
pub columns: usize,
pub max_rows: Option<usize>,
pub max_columns: Option<usize>,
pub cols: usize,
// FIXME: Honestly, these shouldn't exist and rows / columns should be enums like:
// Dimension::Flex(usize) / Dimension::Fixed(usize), but 400+ compiler errors is more than
// I'm in the mood for right now...
pub rows_fixed: bool,
pub cols_fixed: bool,
}
impl From<Winsize> for PositionAndSize {
fn from(winsize: Winsize) -> PositionAndSize {
PositionAndSize {
columns: winsize.ws_col as usize,
cols: winsize.ws_col as usize,
rows: winsize.ws_row as usize,
..Default::default()
}