From 77670cbc7c86d6f0b3e300bcac72e435aff6f690 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Mon, 22 Aug 2022 18:24:58 -0700 Subject: [PATCH] Added scroll-to-edge. --- crates/editor/src/element.rs | 2 +- crates/terminal/src/mappings/mouse.rs | 11 ++-- crates/terminal/src/terminal.rs | 72 ++++++++++++++++++------- crates/terminal/src/terminal_element.rs | 2 +- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index a2fe64f7a4..f6cc2796b1 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -2006,7 +2006,7 @@ impl HighlightedRange { } } -fn scale_vertical_mouse_autoscroll_delta(delta: f32) -> f32 { +pub fn scale_vertical_mouse_autoscroll_delta(delta: f32) -> f32 { delta.powf(1.5) / 100.0 } diff --git a/crates/terminal/src/mappings/mouse.rs b/crates/terminal/src/mappings/mouse.rs index 83d408e75f..c90cbb5cd3 100644 --- a/crates/terminal/src/mappings/mouse.rs +++ b/crates/terminal/src/mappings/mouse.rs @@ -33,12 +33,11 @@ impl Modifiers { } } - //TODO: Determine if I should add modifiers into the ScrollWheelEvent type - fn from_scroll() -> Self { + fn from_scroll(scroll: &ScrollWheelEvent) -> Self { Modifiers { - ctrl: false, - shift: false, - alt: false, + ctrl: scroll.ctrl, + shift: scroll.shift, + alt: scroll.alt, } } } @@ -123,7 +122,7 @@ pub fn scroll_report( point, MouseButton::from_scroll(e), true, - Modifiers::from_scroll(), + Modifiers::from_scroll(e), MouseFormat::from_mode(mode), ) .map(|report| repeat(report).take(max(scroll_lines, 1) as usize)) diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 3adaf7fa7c..b44c7738b2 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -18,7 +18,6 @@ use alacritty_terminal::{ Term, }; use anyhow::{bail, Result}; - use futures::{ channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, FutureExt, @@ -33,7 +32,10 @@ use std::{collections::HashMap, fmt::Display, ops::Sub, path::PathBuf, sync::Arc use thiserror::Error; use gpui::{ - geometry::vector::{vec2f, Vector2F}, + geometry::{ + rect::RectF, + vector::{vec2f, Vector2F}, + }, keymap::Keystroke, ClipboardItem, Entity, ModelContext, MouseButton, MouseButtonEvent, MouseMovedEvent, MutableAppContext, ScrollWheelEvent, @@ -310,11 +312,8 @@ impl TerminalBuilder { term.set_mode(alacritty_terminal::ansi::Mode::BlinkingCursor) } - //Start alternate_scroll if we need to - if let AlternateScroll::On = alternate_scroll { - term.set_mode(alacritty_terminal::ansi::Mode::AlternateScroll) - } else { - //Alacritty turns it on by default, so we need to turn it off. + //Alacritty defaults to alternate scrolling being on, so we just need to turn it off. + if let AlternateScroll::Off = alternate_scroll { term.unset_mode(alacritty_terminal::ansi::Mode::AlternateScroll) } @@ -369,6 +368,7 @@ impl TerminalBuilder { cur_size: initial_size, last_mouse: None, last_offset: 0, + current_selection: false, }; Ok(TerminalBuilder { @@ -440,6 +440,7 @@ pub struct Terminal { last_mode: TermMode, last_offset: usize, last_mouse: Option<(Point, Direction)>, + current_selection: bool, } impl Terminal { @@ -530,10 +531,19 @@ impl Terminal { } } - pub fn input(&mut self, input: String) { - self.events.push(InternalEvent::Scroll(Scroll::Bottom)); + fn begin_select(&mut self, sel: Selection) { + self.current_selection = true; + self.events.push(InternalEvent::SetSelection(Some(sel))); + } + + fn continue_selection(&mut self, point: Point, direction: Direction) { + self.events + .push(InternalEvent::UpdateSelection((point, direction))) + } + + fn end_select(&mut self) { + self.current_selection = false; self.events.push(InternalEvent::SetSelection(None)); - self.write_to_pty(input); } ///Write the Input payload to the tty. @@ -541,6 +551,12 @@ impl Terminal { self.pty_tx.notify(input.into_bytes()); } + pub fn input(&mut self, input: String) { + self.events.push(InternalEvent::Scroll(Scroll::Bottom)); + self.end_select(); + self.write_to_pty(input); + } + ///Resize the terminal and the PTY. pub fn set_size(&mut self, new_size: TerminalSize) { self.events.push(InternalEvent::Resize(new_size)) @@ -642,15 +658,34 @@ impl Terminal { } } - pub fn mouse_drag(&mut self, e: MouseMovedEvent, origin: Vector2F) { + pub fn mouse_drag(&mut self, e: MouseMovedEvent, origin: Vector2F, bounds: RectF) { let position = e.position.sub(origin); if !self.mouse_mode(e.shift) { let point = mouse_point(position, self.cur_size, self.last_offset); let side = mouse_side(position, self.cur_size); - self.events - .push(InternalEvent::UpdateSelection((point, side))); + // Alacritty has the same ordering, of first updating the selection + // then scrolling 15ms later + self.continue_selection(point, side); + + // Doesn't make sense to scroll the alt screen + if !self.last_mode.contains(TermMode::ALT_SCREEN) { + let top = bounds.origin_y() + self.cur_size.line_height; + let bottom = bounds.lower_left().y() - self.cur_size.line_height; + + let scroll_delta = if e.position.y() < top { + top - e.position.y() + } else if e.position.y() > bottom { + -(e.position.y() - bottom) + } else { + return; //Nothing to do + }; + + let scroll_lines = (dbg!(scroll_delta) / self.cur_size.line_height) as i32; + self.events + .push(InternalEvent::Scroll(Scroll::Delta(dbg!(scroll_lines)))) + } } } @@ -664,12 +699,7 @@ impl Terminal { self.pty_tx.notify(bytes); } } else if e.button == MouseButton::Left { - self.events - .push(InternalEvent::SetSelection(Some(Selection::new( - SelectionType::Simple, - point, - side, - )))); + self.begin_select(Selection::new(SelectionType::Simple, point, side)); } } @@ -691,7 +721,9 @@ impl Terminal { let selection = selection_type.map(|selection_type| Selection::new(selection_type, point, side)); - self.events.push(InternalEvent::SetSelection(selection)); + if let Some(sel) = selection { + self.begin_select(sel); + } } } diff --git a/crates/terminal/src/terminal_element.rs b/crates/terminal/src/terminal_element.rs index 66820c727f..3667b7aef5 100644 --- a/crates/terminal/src/terminal_element.rs +++ b/crates/terminal/src/terminal_element.rs @@ -457,7 +457,7 @@ impl TerminalElement { if cx.is_parent_view_focused() { if let Some(conn_handle) = connection.upgrade(cx.app) { conn_handle.update(cx.app, |terminal, cx| { - terminal.mouse_drag(event, origin); + terminal.mouse_drag(event, origin, visible_bounds); cx.notify(); }) }