summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/tab/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'zellij-server/src/tab/mod.rs')
-rw-r--r--zellij-server/src/tab/mod.rs256
1 files changed, 201 insertions, 55 deletions
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index 44c2a480f..750f49447 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -296,8 +296,32 @@ pub trait Pane {
fn load_pane_name(&mut self);
fn set_borderless(&mut self, borderless: bool);
fn borderless(&self) -> bool;
+ // TODO: this should probably be merged with the mouse_right_click
fn handle_right_click(&mut self, _to: &Position, _client_id: ClientId) {}
- fn mouse_mode(&self) -> bool;
+ fn mouse_left_click(&self, _position: &Position, _is_held: bool) -> Option<String> {
+ None
+ }
+ fn mouse_left_click_release(&self, _position: &Position) -> Option<String> {
+ None
+ }
+ fn mouse_right_click(&self, _position: &Position, _is_held: bool) -> Option<String> {
+ None
+ }
+ fn mouse_right_click_release(&self, _position: &Position) -> Option<String> {
+ None
+ }
+ fn mouse_middle_click(&self, _position: &Position, _is_held: bool) -> Option<String> {
+ None
+ }
+ fn mouse_middle_click_release(&self, _position: &Position) -> Option<String> {
+ None
+ }
+ fn mouse_scroll_up(&self, _position: &Position) -> Option<String> {
+ None
+ }
+ fn mouse_scroll_down(&self, _position: &Position) -> Option<String> {
+ None
+ }
fn get_line_number(&self) -> Option<usize> {
None
}
@@ -1668,13 +1692,8 @@ impl Tab {
}
pub fn scroll_terminal_up(&mut self, point: &Position, lines: usize, client_id: ClientId) {
if let Some(pane) = self.get_pane_at(point, false) {
- if pane.mouse_mode() {
- let relative_position = pane.relative_position(point);
- let mouse_event = format!(
- "\u{1b}[<64;{:?};{:?}M",
- relative_position.column.0 + 1,
- relative_position.line.0 + 1
- );
+ let relative_position = pane.relative_position(point);
+ if let Some(mouse_event) = pane.mouse_scroll_up(&relative_position) {
self.write_to_terminal_at(mouse_event.into_bytes(), point);
} else {
pane.scroll_up(lines, client_id);
@@ -1683,13 +1702,8 @@ impl Tab {
}
pub fn scroll_terminal_down(&mut self, point: &Position, lines: usize, client_id: ClientId) {
if let Some(pane) = self.get_pane_at(point, false) {
- if pane.mouse_mode() {
- let relative_position = pane.relative_position(point);
- let mouse_event = format!(
- "\u{1b}[<65;{:?};{:?}M",
- relative_position.column.0 + 1,
- relative_position.line.0 + 1
- );
+ let relative_position = pane.relative_position(point);
+ if let Some(mouse_event) = pane.mouse_scroll_down(&relative_position) {
self.write_to_terminal_at(mouse_event.into_bytes(), point);
} else {
pane.scroll_down(lines, client_id);
@@ -1755,18 +1769,11 @@ impl Tab {
if let Some(pane) = self.get_pane_at(position, false) {
let relative_position = pane.relative_position(position);
-
- if pane.mouse_mode() {
+ if let Some(mouse_event) = pane.mouse_left_click(&relative_position, false) {
if !pane.position_is_on_frame(position) {
- let mouse_event = format!(
- "\u{1b}[<0;{:?};{:?}M",
- relative_position.column() + 1,
- relative_position.line() + 1
- );
self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
}
} else {
- // TODO: rename this method, it is used to forward click events to plugin panes
pane.start_selection(&relative_position, client_id);
if let PaneId::Terminal(_) = pane.pid() {
self.selecting_with_mouse = true;
@@ -1779,13 +1786,8 @@ impl Tab {
if let Some(pane) = self.get_pane_at(position, false) {
let relative_position = pane.relative_position(position);
- if pane.mouse_mode() {
+ if let Some(mouse_event) = pane.mouse_right_click(&relative_position, false) {
if !pane.position_is_on_frame(position) {
- let mouse_event = format!(
- "\u{1b}[<2;{:?};{:?}M",
- relative_position.column() + 1,
- relative_position.line() + 1
- );
self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
}
} else {
@@ -1793,6 +1795,18 @@ impl Tab {
}
};
}
+ pub fn handle_middle_click(&mut self, position: &Position, client_id: ClientId) {
+ self.focus_pane_at(position, client_id);
+
+ if let Some(pane) = self.get_pane_at(position, false) {
+ let relative_position = pane.relative_position(position);
+ if let Some(mouse_event) = pane.mouse_middle_click(&relative_position, false) {
+ if !pane.position_is_on_frame(position) {
+ self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
+ }
+ }
+ };
+ }
fn focus_pane_at(&mut self, point: &Position, client_id: ClientId) {
if self.floating_panes.panes_are_visible() {
if let Some(clicked_pane) = self.floating_panes.get_pane_id_at(point, true) {
@@ -1810,7 +1824,51 @@ impl Tab {
}
}
}
- pub fn handle_mouse_release(&mut self, position: &Position, client_id: ClientId) {
+ pub fn handle_right_mouse_release(&mut self, position: &Position, client_id: ClientId) {
+ self.last_mouse_hold_position = None;
+ let active_pane = self.get_active_pane_or_floating_pane_mut(client_id);
+ if let Some(active_pane) = active_pane {
+ let mut relative_position = active_pane.relative_position(position);
+ relative_position.change_column(
+ (relative_position.column())
+ .max(0)
+ .min(active_pane.get_content_columns()),
+ );
+
+ relative_position.change_line(
+ (relative_position.line())
+ .max(0)
+ .min(active_pane.get_content_rows() as isize),
+ );
+
+ if let Some(mouse_event) = active_pane.mouse_right_click_release(&relative_position) {
+ self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
+ }
+ }
+ }
+ pub fn handle_middle_mouse_release(&mut self, position: &Position, client_id: ClientId) {
+ self.last_mouse_hold_position = None;
+ let active_pane = self.get_active_pane_or_floating_pane_mut(client_id);
+ if let Some(active_pane) = active_pane {
+ let mut relative_position = active_pane.relative_position(position);
+ relative_position.change_column(
+ (relative_position.column())
+ .max(0)
+ .min(active_pane.get_content_columns()),
+ );
+
+ relative_position.change_line(
+ (relative_position.line())
+ .max(0)
+ .min(active_pane.get_content_rows() as isize),
+ );
+
+ if let Some(mouse_event) = active_pane.mouse_middle_click_release(&relative_position) {
+ self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
+ }
+ }
+ }
+ pub fn handle_left_mouse_release(&mut self, position: &Position, client_id: ClientId) {
self.last_mouse_hold_position = None;
if self.floating_panes.panes_are_visible()
@@ -1826,20 +1884,23 @@ impl Tab {
let active_pane = self.get_active_pane_or_floating_pane_mut(client_id);
if let Some(active_pane) = active_pane {
- let relative_position = active_pane.relative_position(position);
- if active_pane.mouse_mode() {
- // ensure that coordinates are valid
- let col = (relative_position.column() + 1)
- .max(1)
- .min(active_pane.get_content_columns());
-
- let line = (relative_position.line() + 1)
- .max(1)
- .min(active_pane.get_content_rows() as isize);
- let mouse_event = format!("\u{1b}[<0;{:?};{:?}m", col, line);
+ let mut relative_position = active_pane.relative_position(position);
+ relative_position.change_column(
+ (relative_position.column())
+ .max(0)
+ .min(active_pane.get_content_columns()),
+ );
+
+ relative_position.change_line(
+ (relative_position.line())
+ .max(0)
+ .min(active_pane.get_content_rows() as isize),
+ );
+
+ if let Some(mouse_event) = active_pane.mouse_left_click_release(&relative_position) {
self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
} else {
- // TODO: rename this method, it is used to forward release events to plugin panes
+ let relative_position = active_pane.relative_position(position);
if let PaneId::Terminal(_) = active_pane.pid() {
if selecting && copy_on_release {
active_pane.end_selection(&relative_position, client_id);
@@ -1858,7 +1919,7 @@ impl Tab {
}
}
}
- pub fn handle_mouse_hold(
+ pub fn handle_mouse_hold_left(
&mut self,
position_on_screen: &Position,
client_id: ClientId,
@@ -1889,20 +1950,24 @@ impl Tab {
let active_pane = self.get_active_pane_or_floating_pane_mut(client_id);
if let Some(active_pane) = active_pane {
- let relative_position = active_pane.relative_position(position_on_screen);
- if active_pane.mouse_mode() && !is_repeated {
+ let mut relative_position = active_pane.relative_position(position_on_screen);
+ if !is_repeated {
// ensure that coordinates are valid
- let col = (relative_position.column() + 1)
- .max(1)
- .min(active_pane.get_content_columns());
-
- let line = (relative_position.line() + 1)
- .max(1)
- .min(active_pane.get_content_rows() as isize);
+ relative_position.change_column(
+ (relative_position.column())
+ .max(0)
+ .min(active_pane.get_content_columns()),
+ );
- let mouse_event = format!("\u{1b}[<32;{:?};{:?}M", col, line);
- self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
- return true; // we need to re-render in this case so the selection disappears
+ relative_position.change_line(
+ (relative_position.line())
+ .max(0)
+ .min(active_pane.get_content_rows() as isize),
+ );
+ if let Some(mouse_event) = active_pane.mouse_left_click(&relative_position, true) {
+ self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
+ return true; // we need to re-render in this case so the selection disappears
+ }
} else if selecting {
active_pane.update_selection(&relative_position, client_id);
return true; // we need to re-render in this case so the selection is updated
@@ -1910,6 +1975,87 @@ impl Tab {
}
false // we shouldn't even get here, but might as well not needlessly render if we do
}
+ pub fn handle_mouse_hold_right(
+ &mut self,
+ position_on_screen: &Position,
+ client_id: ClientId,
+ ) -> bool {
+ // return value indicates whether we should trigger a render
+ // determine if event is repeated to enable smooth scrolling
+ let is_repeated = if let Some(last_position) = self.last_mouse_hold_position {
+ position_on_screen == &last_position
+ } else {
+ false
+ };
+ self.last_mouse_hold_position = Some(*position_on_screen);
+
+ let active_pane = self.get_active_pane_or_floating_pane_mut(client_id);
+
+ if let Some(active_pane) = active_pane {
+ let mut relative_position = active_pane.relative_position(position_on_screen);
+ if !is_repeated {
+ relative_position.change_column(
+ (relative_position.column())
+ .max(0)
+ .min(active_pane.get_content_columns()),
+ );
+
+ relative_position.change_line(
+ (relative_position.line())
+ .max(0)
+ .min(active_pane.get_content_rows() as isize),
+ );
+ if let Some(mouse_event) = active_pane.mouse_right_click(&relative_position, true) {
+ self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
+ return true; // we need to re-render in this case so the selection disappears
+ }
+ }
+ }
+ false // we shouldn't even get here, but might as well not needlessly render if we do
+ }
+ pub fn handle_mouse_hold_middle(
+ &mut self,
+ position_on_screen: &Position,
+ client_id: ClientId,
+ ) -> bool {
+ println!("mouse hold middle");
+ // return value indicates whether we should trigger a render
+ // determine if event is repeated to enable smooth scrolling
+ let is_repeated = if let Some(last_position) = self.last_mouse_hold_position {
+ position_on_screen == &last_position
+ } else {
+ false
+ };
+ println!("is repeated: {:?}", is_repeated);
+ self.last_mouse_hold_position = Some(*position_on_screen);
+
+ let active_pane = self.get_active_pane_or_floating_pane_mut(client_id);
+
+ if let Some(active_pane) = active_pane {
+ println!("can have active pane");
+ let mut relative_position = active_pane.relative_position(position_on_screen);
+ if !is_repeated {
+ relative_position.change_column(
+ (relative_position.column())
+ .max(0)
+ .min(active_pane.get_content_columns()),
+ );
+
+ relative_position.change_line(
+ (relative_position.line())
+ .max(0)
+ .min(active_pane.get_content_rows() as isize),
+ );
+ if let Some(mouse_event) = active_pane.mouse_middle_click(&relative_position, true)
+ {
+ log::info!("can have mouse event: {:?}", mouse_event);
+ self.write_to_active_terminal(mouse_event.into_bytes(), client_id);
+ return true; // we need to re-render in this case so the selection disappears
+ }
+ }
+ }
+ false // we shouldn't even get here, but might as well not needlessly render if we do
+ }
pub fn copy_selection(&self, client_id: ClientId) {
let selected_text = self