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",
"down": "terminal::DOWN",
"tab": "terminal::TAB",
"cmd-k": "terminal::Clear",
"cmd-v": "terminal::Paste"
}
}

View file

@ -703,6 +703,20 @@ impl<'a> EventContext<'a> {
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>) {
self.dispatched_actions.push(DispatchDirective {
dispatcher_view_id: self.view_stack.last().copied(),

View file

@ -17,12 +17,12 @@ use gpui::{
geometry::{rect::RectF, vector::vec2f},
json::json,
text_layout::Line,
Event, Quad,
Event, MouseRegion, Quad,
};
use mio_extras::channel::Sender;
use ordered_float::OrderedFloat;
use settings::Settings;
use std::sync::Arc;
use std::{rc::Rc, sync::Arc};
use theme::TerminalStyle;
use crate::{Input, ZedListener};
@ -33,6 +33,7 @@ pub struct TerminalEl {
term: Arc<FairMutex<Term<ZedListener>>>,
pty_tx: Sender<Msg>,
size: SizeInfo,
view_id: usize,
}
impl TerminalEl {
@ -40,8 +41,14 @@ impl TerminalEl {
term: Arc<FairMutex<Term<ZedListener>>>,
pty_tx: Sender<Msg>,
size: SizeInfo,
view_id: usize,
) -> 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,
) -> Self::PaintState {
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 mut line_origin = origin;
@ -214,24 +236,34 @@ impl Element for TerminalEl {
&mut self,
event: &gpui::Event,
_bounds: gpui::geometry::rect::RectF,
_visible_bounds: gpui::geometry::rect::RectF,
visible_bounds: gpui::geometry::rect::RectF,
layout: &mut Self::LayoutState,
_paint: &mut Self::PaintState,
cx: &mut gpui::EventContext,
) -> bool {
match event {
Event::ScrollWheel { delta, .. } => {
let vertical_scroll =
(delta.y() / layout.line_height) * ALACRITTY_SCROLL_MULTIPLIER;
let scroll = Scroll::Delta(vertical_scroll.round() as i32);
self.term.lock().scroll_display(scroll);
true
Event::ScrollWheel {
delta, position, ..
} => {
if visible_bounds.contains_point(*position) {
let vertical_scroll =
(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 {
input: Some(input), ..
} => {
cx.dispatch_action(Input(input.to_string()));
true
if cx.is_parent_view_focused() {
cx.dispatch_action(Input(input.to_string()));
true
} else {
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
}
enum ZedTermEvent {
enum Event {
TitleChanged,
CloseTerminal,
Activate,
}
impl Entity for Terminal {
type Event = ZedTermEvent;
type Event = Event;
}
impl Terminal {
@ -166,7 +167,7 @@ impl Terminal {
if !cx.is_self_focused() {
//Need to figure out how to trigger a redraw when not in focus
self.has_new_content = true; //Change tab content
cx.emit(ZedTermEvent::TitleChanged);
cx.emit(Event::TitleChanged);
} else {
cx.notify()
}
@ -180,11 +181,11 @@ impl Terminal {
}
AlacTermEvent::Title(title) => {
self.title = title;
cx.emit(ZedTermEvent::TitleChanged);
cx.emit(Event::TitleChanged);
}
AlacTermEvent::ResetTitle => {
self.title = DEFAULT_TITLE.to_string();
cx.emit(ZedTermEvent::TitleChanged);
cx.emit(Event::TitleChanged);
}
AlacTermEvent::ClipboardStore(_, data) => {
cx.write_to_clipboard(ClipboardItem::new(data))
@ -209,7 +210,7 @@ impl Terminal {
}
AlacTermEvent::Bell => {
self.has_bell = true;
cx.emit(ZedTermEvent::TitleChanged);
cx.emit(Event::TitleChanged);
}
AlacTermEvent::Exit => self.quit(&Quit, cx),
}
@ -226,7 +227,7 @@ impl Terminal {
}
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>) {
@ -239,7 +240,7 @@ impl Terminal {
//iTerm bell behavior, bell stays until terminal is interacted with
self.has_bell = false;
self.term.lock().scroll_display(Scroll::Bottom);
cx.emit(ZedTermEvent::TitleChanged);
cx.emit(Event::TitleChanged);
self.pty_tx.notify(input.0.clone().into_bytes());
}
@ -301,13 +302,19 @@ impl View for Terminal {
//TODO: derive this
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)
.contained()
// .with_style(theme.terminal.container)
.boxed()
TerminalEl::new(
self.term.clone(),
self.pty_tx.0.clone(),
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;
}
}
@ -392,10 +399,14 @@ impl Item for Terminal {
}
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 {
matches!(event, &ZedTermEvent::CloseTerminal)
matches!(event, &Event::CloseTerminal)
}
fn should_activate_item_on_event(event: &Self::Event) -> bool {
matches!(event, &Event::Activate)
}
}