@@ -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(),
@@ -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,
}
@@ -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)
}
}