mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 02:46:43 +00:00
Fixed focus issues with scrolling and input
This commit is contained in:
parent
38ed70d5cc
commit
e3834409dd
4 changed files with 84 additions and 28 deletions
|
@ -366,7 +366,6 @@
|
|||
"up": "terminal::UP",
|
||||
"down": "terminal::DOWN",
|
||||
"tab": "terminal::TAB",
|
||||
"cmd-k": "terminal::Clear",
|
||||
"cmd-v": "terminal::Paste"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue