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",
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue