Fixed focus issues with scrolling and input

This commit is contained in:
Mikayla Maki 2022-06-28 18:28:13 -07:00
parent 38ed70d5cc
commit e3834409dd
4 changed files with 84 additions and 28 deletions

View file

@ -366,7 +366,6 @@
"up": "terminal::UP", "up": "terminal::UP",
"down": "terminal::DOWN", "down": "terminal::DOWN",
"tab": "terminal::TAB", "tab": "terminal::TAB",
"cmd-k": "terminal::Clear",
"cmd-v": "terminal::Paste" "cmd-v": "terminal::Paste"
} }
} }

View file

@ -703,6 +703,20 @@ impl<'a> EventContext<'a> {
self.view_stack.last().copied() self.view_stack.last().copied()
} }
pub fn is_parent_view_focused(&self) -> bool {
if let Some(parent_view_id) = self.view_stack.last() {
self.app.focused_view_id(self.window_id) == Some(*parent_view_id)
} else {
false
}
}
pub fn focus_parent_view(&mut self) {
if let Some(parent_view_id) = self.view_stack.last() {
self.app.focus(self.window_id, Some(*parent_view_id))
}
}
pub fn dispatch_any_action(&mut self, action: Box<dyn Action>) { pub fn dispatch_any_action(&mut self, action: Box<dyn Action>) {
self.dispatched_actions.push(DispatchDirective { self.dispatched_actions.push(DispatchDirective {
dispatcher_view_id: self.view_stack.last().copied(), dispatcher_view_id: self.view_stack.last().copied(),

View file

@ -17,12 +17,12 @@ use gpui::{
geometry::{rect::RectF, vector::vec2f}, geometry::{rect::RectF, vector::vec2f},
json::json, json::json,
text_layout::Line, text_layout::Line,
Event, Quad, Event, MouseRegion, Quad,
}; };
use mio_extras::channel::Sender; use mio_extras::channel::Sender;
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use settings::Settings; use settings::Settings;
use std::sync::Arc; use std::{rc::Rc, sync::Arc};
use theme::TerminalStyle; use theme::TerminalStyle;
use crate::{Input, ZedListener}; use crate::{Input, ZedListener};
@ -33,6 +33,7 @@ pub struct TerminalEl {
term: Arc<FairMutex<Term<ZedListener>>>, term: Arc<FairMutex<Term<ZedListener>>>,
pty_tx: Sender<Msg>, pty_tx: Sender<Msg>,
size: SizeInfo, size: SizeInfo,
view_id: usize,
} }
impl TerminalEl { impl TerminalEl {
@ -40,8 +41,14 @@ impl TerminalEl {
term: Arc<FairMutex<Term<ZedListener>>>, term: Arc<FairMutex<Term<ZedListener>>>,
pty_tx: Sender<Msg>, pty_tx: Sender<Msg>,
size: SizeInfo, size: SizeInfo,
view_id: usize,
) -> TerminalEl { ) -> TerminalEl {
TerminalEl { term, pty_tx, size } TerminalEl {
term,
pty_tx,
size,
view_id,
}
} }
} }
@ -183,6 +190,21 @@ impl Element for TerminalEl {
cx: &mut gpui::PaintContext, cx: &mut gpui::PaintContext,
) -> Self::PaintState { ) -> Self::PaintState {
cx.scene.push_layer(Some(visible_bounds)); cx.scene.push_layer(Some(visible_bounds));
cx.scene.push_mouse_region(MouseRegion {
view_id: self.view_id,
discriminant: None,
bounds: visible_bounds,
hover: None,
mouse_down: Some(Rc::new(|_, cx| cx.focus_parent_view())),
click: None,
right_mouse_down: None,
right_click: None,
drag: None,
mouse_down_out: None,
right_mouse_down_out: None,
});
let origin = bounds.origin() + vec2f(layout.em_width, 0.); let origin = bounds.origin() + vec2f(layout.em_width, 0.);
let mut line_origin = origin; let mut line_origin = origin;
@ -214,24 +236,34 @@ impl Element for TerminalEl {
&mut self, &mut self,
event: &gpui::Event, event: &gpui::Event,
_bounds: gpui::geometry::rect::RectF, _bounds: gpui::geometry::rect::RectF,
_visible_bounds: gpui::geometry::rect::RectF, visible_bounds: gpui::geometry::rect::RectF,
layout: &mut Self::LayoutState, layout: &mut Self::LayoutState,
_paint: &mut Self::PaintState, _paint: &mut Self::PaintState,
cx: &mut gpui::EventContext, cx: &mut gpui::EventContext,
) -> bool { ) -> bool {
match event { match event {
Event::ScrollWheel { delta, .. } => { Event::ScrollWheel {
let vertical_scroll = delta, position, ..
(delta.y() / layout.line_height) * ALACRITTY_SCROLL_MULTIPLIER; } => {
let scroll = Scroll::Delta(vertical_scroll.round() as i32); if visible_bounds.contains_point(*position) {
self.term.lock().scroll_display(scroll); let vertical_scroll =
true (delta.y() / layout.line_height) * ALACRITTY_SCROLL_MULTIPLIER;
let scroll = Scroll::Delta(vertical_scroll.round() as i32);
self.term.lock().scroll_display(scroll);
true
} else {
false
}
} }
Event::KeyDown { Event::KeyDown {
input: Some(input), .. input: Some(input), ..
} => { } => {
cx.dispatch_action(Input(input.to_string())); if cx.is_parent_view_focused() {
true cx.dispatch_action(Input(input.to_string()));
true
} else {
false
}
} }
_ => false, _ => false,
} }

View file

@ -84,13 +84,14 @@ struct Terminal {
has_bell: bool, //Currently using iTerm bell, show bell emoji in tab until input is received has_bell: bool, //Currently using iTerm bell, show bell emoji in tab until input is received
} }
enum ZedTermEvent { enum Event {
TitleChanged, TitleChanged,
CloseTerminal, CloseTerminal,
Activate,
} }
impl Entity for Terminal { impl Entity for Terminal {
type Event = ZedTermEvent; type Event = Event;
} }
impl Terminal { impl Terminal {
@ -166,7 +167,7 @@ impl Terminal {
if !cx.is_self_focused() { if !cx.is_self_focused() {
//Need to figure out how to trigger a redraw when not in focus //Need to figure out how to trigger a redraw when not in focus
self.has_new_content = true; //Change tab content self.has_new_content = true; //Change tab content
cx.emit(ZedTermEvent::TitleChanged); cx.emit(Event::TitleChanged);
} else { } else {
cx.notify() cx.notify()
} }
@ -180,11 +181,11 @@ impl Terminal {
} }
AlacTermEvent::Title(title) => { AlacTermEvent::Title(title) => {
self.title = title; self.title = title;
cx.emit(ZedTermEvent::TitleChanged); cx.emit(Event::TitleChanged);
} }
AlacTermEvent::ResetTitle => { AlacTermEvent::ResetTitle => {
self.title = DEFAULT_TITLE.to_string(); self.title = DEFAULT_TITLE.to_string();
cx.emit(ZedTermEvent::TitleChanged); cx.emit(Event::TitleChanged);
} }
AlacTermEvent::ClipboardStore(_, data) => { AlacTermEvent::ClipboardStore(_, data) => {
cx.write_to_clipboard(ClipboardItem::new(data)) cx.write_to_clipboard(ClipboardItem::new(data))
@ -209,7 +210,7 @@ impl Terminal {
} }
AlacTermEvent::Bell => { AlacTermEvent::Bell => {
self.has_bell = true; self.has_bell = true;
cx.emit(ZedTermEvent::TitleChanged); cx.emit(Event::TitleChanged);
} }
AlacTermEvent::Exit => self.quit(&Quit, cx), AlacTermEvent::Exit => self.quit(&Quit, cx),
} }
@ -226,7 +227,7 @@ impl Terminal {
} }
fn quit(&mut self, _: &Quit, cx: &mut ViewContext<Self>) { fn quit(&mut self, _: &Quit, cx: &mut ViewContext<Self>) {
cx.emit(ZedTermEvent::CloseTerminal); cx.emit(Event::CloseTerminal);
} }
fn paste(&mut self, _: &Paste, cx: &mut ViewContext<Self>) { fn paste(&mut self, _: &Paste, cx: &mut ViewContext<Self>) {
@ -239,7 +240,7 @@ impl Terminal {
//iTerm bell behavior, bell stays until terminal is interacted with //iTerm bell behavior, bell stays until terminal is interacted with
self.has_bell = false; self.has_bell = false;
self.term.lock().scroll_display(Scroll::Bottom); self.term.lock().scroll_display(Scroll::Bottom);
cx.emit(ZedTermEvent::TitleChanged); cx.emit(Event::TitleChanged);
self.pty_tx.notify(input.0.clone().into_bytes()); self.pty_tx.notify(input.0.clone().into_bytes());
} }
@ -301,13 +302,19 @@ impl View for Terminal {
//TODO: derive this //TODO: derive this
let size_info = SizeInfo::new(400., 100.0, 5., 5., 0., 0., false); let size_info = SizeInfo::new(400., 100.0, 5., 5., 0., 0., false);
TerminalEl::new(self.term.clone(), self.pty_tx.0.clone(), size_info) TerminalEl::new(
.contained() self.term.clone(),
// .with_style(theme.terminal.container) self.pty_tx.0.clone(),
.boxed() size_info,
cx.view_id(),
)
.contained()
// .with_style(theme.terminal.container)
.boxed()
} }
fn on_focus(&mut self, _: &mut ViewContext<Self>) { fn on_focus(&mut self, cx: &mut ViewContext<Self>) {
cx.emit(Event::Activate);
self.has_new_content = false; self.has_new_content = false;
} }
} }
@ -392,10 +399,14 @@ impl Item for Terminal {
} }
fn should_update_tab_on_event(event: &Self::Event) -> bool { fn should_update_tab_on_event(event: &Self::Event) -> bool {
matches!(event, &ZedTermEvent::TitleChanged) matches!(event, &Event::TitleChanged)
} }
fn should_close_item_on_event(event: &Self::Event) -> bool { fn should_close_item_on_event(event: &Self::Event) -> bool {
matches!(event, &ZedTermEvent::CloseTerminal) matches!(event, &Event::CloseTerminal)
}
fn should_activate_item_on_event(event: &Self::Event) -> bool {
matches!(event, &Event::Activate)
} }
} }