Skip to content

Commit

Permalink
fix(tab-bar,compact-bar): tab switching with mouse sometimes not work…
Browse files Browse the repository at this point in the history
…ing (zellij-org#2587)

* tab-bar: fix clicks sometimes not registering

Caching the click position wasn't working across multiple plugin
instances.

Also a couple of refactors:
  - move the code with the tab switching logic inside update
  - avoid rendering when calling switch_tab_to, since it will happen
    anyway afterwards

* same fix for compact-bar
  • Loading branch information
tlinford authored Jun 30, 2023
1 parent fda5923 commit 19a502c
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 55 deletions.
40 changes: 12 additions & 28 deletions default-plugins/compact-bar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod tab;
use std::cmp::{max, min};
use std::convert::TryInto;

use tab::get_tab_to_focus;
use zellij_tile::prelude::*;

use crate::line::tab_line;
Expand All @@ -21,8 +22,7 @@ struct State {
tabs: Vec<TabInfo>,
active_tab_idx: usize,
mode_info: ModeInfo,
mouse_click_pos: usize,
should_change_tab: bool,
tab_line: Vec<LinePart>,
}

static ARROW_SEPARATOR: &str = "";
Expand Down Expand Up @@ -63,18 +63,15 @@ impl ZellijPlugin for State {
},
Event::Mouse(me) => match me {
Mouse::LeftClick(_, col) => {
if self.mouse_click_pos != col {
should_render = true;
self.should_change_tab = true;
let tab_to_focus = get_tab_to_focus(&self.tab_line, self.active_tab_idx, col);
if let Some(idx) = tab_to_focus {
switch_tab_to(idx.try_into().unwrap());
}
self.mouse_click_pos = col;
},
Mouse::ScrollUp(_) => {
should_render = true;
switch_tab_to(min(self.active_tab_idx + 1, self.tabs.len()) as u32);
},
Mouse::ScrollDown(_) => {
should_render = true;
switch_tab_to(max(self.active_tab_idx.saturating_sub(1), 1) as u32);
},
_ => {},
Expand Down Expand Up @@ -117,7 +114,7 @@ impl ZellijPlugin for State {
is_alternate_tab = !is_alternate_tab;
all_tabs.push(tab);
}
let tab_line = tab_line(
self.tab_line = tab_line(
self.mode_info.session_name.as_deref(),
all_tabs,
active_tab_index,
Expand All @@ -129,34 +126,21 @@ impl ZellijPlugin for State {
&active_swap_layout_name,
is_swap_layout_dirty,
);
let mut s = String::new();
let mut len_cnt = 0;
for bar_part in tab_line {
s = format!("{}{}", s, &bar_part.part);

if self.should_change_tab
&& self.mouse_click_pos >= len_cnt
&& self.mouse_click_pos < len_cnt + bar_part.len
&& bar_part.tab_index.is_some()
{
// Tabs are indexed starting from 1, therefore we need add 1 to tab_index.
let tab_index: u32 = bar_part.tab_index.unwrap().try_into().unwrap();
switch_tab_to(tab_index + 1);
}
len_cnt += bar_part.len;
}
let output = self
.tab_line
.iter()
.fold(String::new(), |output, part| output + &part.part);
let background = match self.mode_info.style.colors.theme_hue {
ThemeHue::Dark => self.mode_info.style.colors.black,
ThemeHue::Light => self.mode_info.style.colors.white,
};
match background {
PaletteColor::Rgb((r, g, b)) => {
print!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", s, r, g, b);
print!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", output, r, g, b);
},
PaletteColor::EightBit(color) => {
print!("{}\u{1b}[48;5;{}m\u{1b}[0K", s, color);
print!("{}\u{1b}[48;5;{}m\u{1b}[0K", output, color);
},
}
self.should_change_tab = false;
}
}
29 changes: 29 additions & 0 deletions default-plugins/compact-bar/src/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,32 @@ pub fn tab_style(

render_tab(tabname, tab, is_alternate_tab, palette, separator)
}

pub(crate) fn get_tab_to_focus(
tab_line: &[LinePart],
active_tab_idx: usize,
mouse_click_col: usize,
) -> Option<usize> {
let clicked_line_part = get_clicked_line_part(tab_line, mouse_click_col)?;
let clicked_tab_idx = clicked_line_part.tab_index?;
// tabs are indexed starting from 1 so we need to add 1
let clicked_tab_idx = clicked_tab_idx + 1;
if clicked_tab_idx != active_tab_idx {
return Some(clicked_tab_idx);
}
None
}

pub(crate) fn get_clicked_line_part(
tab_line: &[LinePart],
mouse_click_col: usize,
) -> Option<&LinePart> {
let mut len = 0;
for tab_line_part in tab_line {
if mouse_click_col >= len && mouse_click_col < len + tab_line_part.len {
return Some(tab_line_part);
}
len += tab_line_part.len;
}
None
}
41 changes: 14 additions & 27 deletions default-plugins/tab-bar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod tab;
use std::cmp::{max, min};
use std::convert::TryInto;

use tab::get_tab_to_focus;
use zellij_tile::prelude::*;

use crate::line::tab_line;
Expand All @@ -21,8 +22,7 @@ struct State {
tabs: Vec<TabInfo>,
active_tab_idx: usize,
mode_info: ModeInfo,
mouse_click_pos: usize,
should_change_tab: bool,
tab_line: Vec<LinePart>,
}

static ARROW_SEPARATOR: &str = "";
Expand Down Expand Up @@ -52,6 +52,7 @@ impl ZellijPlugin for State {
if let Some(active_tab_index) = tabs.iter().position(|t| t.active) {
// tabs are indexed starting from 1 so we need to add 1
let active_tab_idx = active_tab_index + 1;

if self.active_tab_idx != active_tab_idx || self.tabs != tabs {
should_render = true;
}
Expand All @@ -63,18 +64,15 @@ impl ZellijPlugin for State {
},
Event::Mouse(me) => match me {
Mouse::LeftClick(_, col) => {
if self.mouse_click_pos != col {
should_render = true;
self.should_change_tab = true;
let tab_to_focus = get_tab_to_focus(&self.tab_line, self.active_tab_idx, col);
if let Some(idx) = tab_to_focus {
switch_tab_to(idx.try_into().unwrap());
}
self.mouse_click_pos = col;
},
Mouse::ScrollUp(_) => {
should_render = true;
switch_tab_to(min(self.active_tab_idx + 1, self.tabs.len()) as u32);
},
Mouse::ScrollDown(_) => {
should_render = true;
switch_tab_to(max(self.active_tab_idx.saturating_sub(1), 1) as u32);
},
_ => {},
Expand Down Expand Up @@ -113,7 +111,7 @@ impl ZellijPlugin for State {
is_alternate_tab = !is_alternate_tab;
all_tabs.push(tab);
}
let tab_line = tab_line(
self.tab_line = tab_line(
self.mode_info.session_name.as_deref(),
all_tabs,
active_tab_index,
Expand All @@ -122,34 +120,23 @@ impl ZellijPlugin for State {
self.mode_info.capabilities,
self.mode_info.style.hide_session_name,
);
let mut s = String::new();
let mut len_cnt = 0;
for bar_part in tab_line {
s = format!("{}{}", s, &bar_part.part);

if self.should_change_tab
&& self.mouse_click_pos >= len_cnt
&& self.mouse_click_pos < len_cnt + bar_part.len
&& bar_part.tab_index.is_some()
{
// Tabs are indexed starting from 1, therefore we need add 1 to tab_index.
let tab_index: u32 = bar_part.tab_index.unwrap().try_into().unwrap();
switch_tab_to(tab_index + 1);
}
len_cnt += bar_part.len;
}
let output = self
.tab_line
.iter()
.fold(String::new(), |output, part| output + &part.part);

let background = match self.mode_info.style.colors.theme_hue {
ThemeHue::Dark => self.mode_info.style.colors.black,
ThemeHue::Light => self.mode_info.style.colors.white,
};
match background {
PaletteColor::Rgb((r, g, b)) => {
print!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", s, r, g, b);
print!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", output, r, g, b);
},
PaletteColor::EightBit(color) => {
print!("{}\u{1b}[48;5;{}m\u{1b}[0K", s, color);
print!("{}\u{1b}[48;5;{}m\u{1b}[0K", output, color);
},
}
self.should_change_tab = false;
}
}
29 changes: 29 additions & 0 deletions default-plugins/tab-bar/src/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,32 @@ pub fn tab_style(

render_tab(tabname, tab, is_alternate_tab, palette, separator)
}

pub(crate) fn get_tab_to_focus(
tab_line: &[LinePart],
active_tab_idx: usize,
mouse_click_col: usize,
) -> Option<usize> {
let clicked_line_part = get_clicked_line_part(tab_line, mouse_click_col)?;
let clicked_tab_idx = clicked_line_part.tab_index?;
// tabs are indexed starting from 1 so we need to add 1
let clicked_tab_idx = clicked_tab_idx + 1;
if clicked_tab_idx != active_tab_idx {
return Some(clicked_tab_idx);
}
None
}

pub(crate) fn get_clicked_line_part(
tab_line: &[LinePart],
mouse_click_col: usize,
) -> Option<&LinePart> {
let mut len = 0;
for tab_line_part in tab_line {
if mouse_click_col >= len && mouse_click_col < len + tab_line_part.len {
return Some(tab_line_part);
}
len += tab_line_part.len;
}
None
}

0 comments on commit 19a502c

Please sign in to comment.