From e3834409ddc4f96b1c3ff7c7b7d154ffa0395f35 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Tue, 28 Jun 2022 18:28:13 -0700 Subject: [PATCH] Fixed focus issues with scrolling and input --- assets/keymaps/default.json | 1 - crates/gpui/src/presenter.rs | 14 +++++++++ crates/terminal/src/element.rs | 56 ++++++++++++++++++++++++++------- crates/terminal/src/terminal.rs | 41 +++++++++++++++--------- 4 files changed, 84 insertions(+), 28 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 232fd4db1f..8da4b2a9ca 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -366,7 +366,6 @@ "up": "terminal::UP", "down": "terminal::DOWN", "tab": "terminal::TAB", - "cmd-k": "terminal::Clear", "cmd-v": "terminal::Paste" } } diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 88e4d0a498..6285b1be99 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -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) { self.dispatched_actions.push(DispatchDirective { dispatcher_view_id: self.view_stack.last().copied(), diff --git a/crates/terminal/src/element.rs b/crates/terminal/src/element.rs index 04828e8d65..08d49ec6d8 100644 --- a/crates/terminal/src/element.rs +++ b/crates/terminal/src/element.rs @@ -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>>, pty_tx: Sender, size: SizeInfo, + view_id: usize, } impl TerminalEl { @@ -40,8 +41,14 @@ impl TerminalEl { term: Arc>>, pty_tx: Sender, 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, } diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index d8335e423b..f375ddbd91 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -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) { - cx.emit(ZedTermEvent::CloseTerminal); + cx.emit(Event::CloseTerminal); } fn paste(&mut self, _: &Paste, cx: &mut ViewContext) { @@ -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) { + fn on_focus(&mut self, cx: &mut ViewContext) { + 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) } }