Merge branch 'main' into drag-and-drop
This commit is contained in:
commit
8591c3f46d
12 changed files with 367 additions and 219 deletions
|
@ -18,7 +18,6 @@ use alacritty_terminal::{
|
|||
Term,
|
||||
};
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
use futures::{
|
||||
channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender},
|
||||
FutureExt,
|
||||
|
@ -29,7 +28,14 @@ use mappings::mouse::{
|
|||
};
|
||||
use modal::deploy_modal;
|
||||
use settings::{AlternateScroll, Settings, Shell, TerminalBlink};
|
||||
use std::{collections::HashMap, fmt::Display, ops::Sub, path::PathBuf, sync::Arc, time::Duration};
|
||||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
fmt::Display,
|
||||
ops::Sub,
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
||||
use gpui::{
|
||||
|
@ -83,7 +89,7 @@ enum InternalEvent {
|
|||
Clear,
|
||||
Scroll(Scroll),
|
||||
SetSelection(Option<Selection>),
|
||||
UpdateSelection((Point, Direction)),
|
||||
UpdateSelection(Vector2F),
|
||||
Copy,
|
||||
}
|
||||
|
||||
|
@ -311,11 +317,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)
|
||||
}
|
||||
|
||||
|
@ -363,13 +366,14 @@ impl TerminalBuilder {
|
|||
let terminal = Terminal {
|
||||
pty_tx: Notifier(pty_tx),
|
||||
term,
|
||||
events: vec![],
|
||||
events: VecDeque::with_capacity(10), //Should never get this high.
|
||||
title: shell_txt.clone(),
|
||||
default_title: shell_txt,
|
||||
last_mode: TermMode::NONE,
|
||||
cur_size: initial_size,
|
||||
last_mouse: None,
|
||||
last_offset: 0,
|
||||
current_selection: false,
|
||||
};
|
||||
|
||||
Ok(TerminalBuilder {
|
||||
|
@ -434,13 +438,14 @@ impl TerminalBuilder {
|
|||
pub struct Terminal {
|
||||
pty_tx: Notifier,
|
||||
term: Arc<FairMutex<Term<ZedListener>>>,
|
||||
events: Vec<InternalEvent>,
|
||||
events: VecDeque<InternalEvent>,
|
||||
default_title: String,
|
||||
title: String,
|
||||
cur_size: TerminalSize,
|
||||
last_mode: TermMode,
|
||||
last_offset: usize,
|
||||
last_mouse: Option<(Point, Direction)>,
|
||||
current_selection: bool,
|
||||
}
|
||||
|
||||
impl Terminal {
|
||||
|
@ -480,9 +485,9 @@ impl Terminal {
|
|||
cx.emit(Event::Wakeup);
|
||||
cx.notify();
|
||||
}
|
||||
AlacTermEvent::ColorRequest(_, _) => {
|
||||
self.events.push(InternalEvent::TermEvent(event.clone()))
|
||||
}
|
||||
AlacTermEvent::ColorRequest(_, _) => self
|
||||
.events
|
||||
.push_back(InternalEvent::TermEvent(event.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,11 +519,16 @@ impl Terminal {
|
|||
self.write_to_pty("\x0c".to_string());
|
||||
term.clear_screen(ClearMode::Saved);
|
||||
}
|
||||
InternalEvent::Scroll(scroll) => term.scroll_display(*scroll),
|
||||
InternalEvent::Scroll(scroll) => {
|
||||
term.scroll_display(*scroll);
|
||||
}
|
||||
InternalEvent::SetSelection(sel) => term.selection = sel.clone(),
|
||||
InternalEvent::UpdateSelection((point, side)) => {
|
||||
InternalEvent::UpdateSelection(position) => {
|
||||
if let Some(mut selection) = term.selection.take() {
|
||||
selection.update(*point, *side);
|
||||
let point = mouse_point(*position, self.cur_size, term.grid().display_offset());
|
||||
let side = mouse_side(*position, self.cur_size);
|
||||
|
||||
selection.update(point, side);
|
||||
term.selection = Some(selection);
|
||||
}
|
||||
}
|
||||
|
@ -531,10 +541,37 @@ impl Terminal {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn input(&mut self, input: String) {
|
||||
self.events.push(InternalEvent::Scroll(Scroll::Bottom));
|
||||
self.events.push(InternalEvent::SetSelection(None));
|
||||
self.write_to_pty(input);
|
||||
fn begin_select(&mut self, sel: Selection) {
|
||||
self.current_selection = true;
|
||||
self.events
|
||||
.push_back(InternalEvent::SetSelection(Some(sel)));
|
||||
}
|
||||
|
||||
fn continue_selection(&mut self, location: Vector2F) {
|
||||
self.events
|
||||
.push_back(InternalEvent::UpdateSelection(location))
|
||||
}
|
||||
|
||||
fn end_select(&mut self) {
|
||||
self.current_selection = false;
|
||||
self.events.push_back(InternalEvent::SetSelection(None));
|
||||
}
|
||||
|
||||
fn scroll(&mut self, scroll: Scroll) {
|
||||
self.events.push_back(InternalEvent::Scroll(scroll));
|
||||
}
|
||||
|
||||
pub fn copy(&mut self) {
|
||||
self.events.push_back(InternalEvent::Copy);
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.events.push_back(InternalEvent::Clear)
|
||||
}
|
||||
|
||||
///Resize the terminal and the PTY.
|
||||
pub fn set_size(&mut self, new_size: TerminalSize) {
|
||||
self.events.push_back(InternalEvent::Resize(new_size))
|
||||
}
|
||||
|
||||
///Write the Input payload to the tty.
|
||||
|
@ -542,13 +579,10 @@ impl Terminal {
|
|||
self.pty_tx.notify(input.into_bytes());
|
||||
}
|
||||
|
||||
///Resize the terminal and the PTY.
|
||||
pub fn set_size(&mut self, new_size: TerminalSize) {
|
||||
self.events.push(InternalEvent::Resize(new_size))
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.events.push(InternalEvent::Clear)
|
||||
pub fn input(&mut self, input: String) {
|
||||
self.scroll(Scroll::Bottom);
|
||||
self.end_select();
|
||||
self.write_to_pty(input);
|
||||
}
|
||||
|
||||
pub fn try_keystroke(&mut self, keystroke: &Keystroke) -> bool {
|
||||
|
@ -571,10 +605,6 @@ impl Terminal {
|
|||
self.input(paste_text)
|
||||
}
|
||||
|
||||
pub fn copy(&mut self) {
|
||||
self.events.push(InternalEvent::Copy);
|
||||
}
|
||||
|
||||
pub fn render_lock<F, T>(&mut self, cx: &mut ModelContext<Self>, f: F) -> T
|
||||
where
|
||||
F: FnOnce(RenderableContent, char) -> T,
|
||||
|
@ -582,7 +612,8 @@ impl Terminal {
|
|||
let m = self.term.clone(); //Arc clone
|
||||
let mut term = m.lock();
|
||||
|
||||
while let Some(e) = self.events.pop() {
|
||||
//Note that this ordering matters for
|
||||
while let Some(e) = self.events.pop_front() {
|
||||
self.process_terminal_event(&e, &mut term, cx)
|
||||
}
|
||||
|
||||
|
@ -647,11 +678,28 @@ impl Terminal {
|
|||
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);
|
||||
// Alacritty has the same ordering, of first updating the selection
|
||||
// then scrolling 15ms later
|
||||
self.continue_selection(position);
|
||||
|
||||
self.events
|
||||
.push(InternalEvent::UpdateSelection((point, side)));
|
||||
// Doesn't make sense to scroll the alt screen
|
||||
if !self.last_mode.contains(TermMode::ALT_SCREEN) {
|
||||
//TODO: Why do these need to be doubled?
|
||||
let top = e.region.origin_y() + (self.cur_size.line_height * 2.);
|
||||
let bottom = e.region.lower_left().y() - (self.cur_size.line_height * 2.);
|
||||
|
||||
let scroll_delta = if e.position.y() < top {
|
||||
(top - e.position.y()).powf(1.1)
|
||||
} else if e.position.y() > bottom {
|
||||
-((e.position.y() - bottom).powf(1.1))
|
||||
} else {
|
||||
return; //Nothing to do
|
||||
};
|
||||
|
||||
let scroll_lines = (scroll_delta / self.cur_size.line_height) as i32;
|
||||
self.scroll(Scroll::Delta(scroll_lines));
|
||||
self.continue_selection(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -665,12 +713,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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,7 +735,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,17 +757,16 @@ impl Terminal {
|
|||
}
|
||||
|
||||
///Scroll the terminal
|
||||
pub fn scroll(&mut self, scroll: &ScrollWheelEvent, origin: Vector2F) {
|
||||
if self.mouse_mode(scroll.shift) {
|
||||
pub fn scroll_wheel(&mut self, e: &ScrollWheelEvent, origin: Vector2F) {
|
||||
if self.mouse_mode(e.shift) {
|
||||
//TODO: Currently this only sends the current scroll reports as they come in. Alacritty
|
||||
//Sends the *entire* scroll delta on *every* scroll event, only resetting it when
|
||||
//The scroll enters 'TouchPhase::Started'. Do I need to replicate this?
|
||||
//This would be consistent with a scroll model based on 'distance from origin'...
|
||||
let scroll_lines = (scroll.delta.y() / self.cur_size.line_height) as i32;
|
||||
let point = mouse_point(scroll.position.sub(origin), self.cur_size, self.last_offset);
|
||||
let scroll_lines = (e.delta.y() / self.cur_size.line_height) as i32;
|
||||
let point = mouse_point(e.position.sub(origin), self.cur_size, self.last_offset);
|
||||
|
||||
if let Some(scrolls) = scroll_report(point, scroll_lines as i32, scroll, self.last_mode)
|
||||
{
|
||||
if let Some(scrolls) = scroll_report(point, scroll_lines as i32, e, self.last_mode) {
|
||||
for scroll in scrolls {
|
||||
self.pty_tx.notify(scroll);
|
||||
}
|
||||
|
@ -730,19 +774,19 @@ impl Terminal {
|
|||
} else if self
|
||||
.last_mode
|
||||
.contains(TermMode::ALT_SCREEN | TermMode::ALTERNATE_SCROLL)
|
||||
&& !scroll.shift
|
||||
&& !e.shift
|
||||
{
|
||||
//TODO: See above TODO, also applies here.
|
||||
let scroll_lines = ((scroll.delta.y() * ALACRITTY_SCROLL_MULTIPLIER)
|
||||
/ self.cur_size.line_height) as i32;
|
||||
let scroll_lines =
|
||||
((e.delta.y() * ALACRITTY_SCROLL_MULTIPLIER) / self.cur_size.line_height) as i32;
|
||||
|
||||
self.pty_tx.notify(alt_scroll(scroll_lines))
|
||||
} else {
|
||||
let scroll_lines = ((scroll.delta.y() * ALACRITTY_SCROLL_MULTIPLIER)
|
||||
/ self.cur_size.line_height) as i32;
|
||||
let scroll_lines =
|
||||
((e.delta.y() * ALACRITTY_SCROLL_MULTIPLIER) / self.cur_size.line_height) as i32;
|
||||
if scroll_lines != 0 {
|
||||
let scroll = Scroll::Delta(scroll_lines);
|
||||
self.events.push(InternalEvent::Scroll(scroll));
|
||||
self.scroll(scroll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue