mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-16 15:11:25 +00:00
Attempt to remove the dangeous element focus API
This commit is contained in:
parent
43b8d65fee
commit
717b2885f8
5 changed files with 39 additions and 80 deletions
|
@ -13,10 +13,10 @@ use editor::{
|
||||||
};
|
};
|
||||||
use futures::future::try_join_all;
|
use futures::future::try_join_all;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, AnyElement, AnyView, AppContext, Context, Div, EventEmitter, FocusEvent,
|
actions, div, AnyElement, AnyView, AppContext, Context, Div, EventEmitter, FocusHandle,
|
||||||
FocusHandle, Focusable, FocusableElement, FocusableView, InteractiveElement, IntoElement,
|
Focusable, FocusableView, InteractiveElement, IntoElement, Model, ParentElement, Render,
|
||||||
Model, ParentElement, Render, SharedString, Styled, Subscription, Task, View, ViewContext,
|
SharedString, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView,
|
||||||
VisualContext, WeakView, WindowContext,
|
WindowContext,
|
||||||
};
|
};
|
||||||
use language::{
|
use language::{
|
||||||
Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection,
|
Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection,
|
||||||
|
@ -109,7 +109,6 @@ impl Render for ProjectDiagnosticsEditor {
|
||||||
div()
|
div()
|
||||||
.track_focus(&self.focus_handle)
|
.track_focus(&self.focus_handle)
|
||||||
.size_full()
|
.size_full()
|
||||||
.on_focus_in(cx.listener(Self::focus_in))
|
|
||||||
.on_action(cx.listener(Self::toggle_warnings))
|
.on_action(cx.listener(Self::toggle_warnings))
|
||||||
.child(child)
|
.child(child)
|
||||||
}
|
}
|
||||||
|
@ -149,6 +148,11 @@ impl ProjectDiagnosticsEditor {
|
||||||
_ => {}
|
_ => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let focus_handle = cx.focus_handle();
|
||||||
|
|
||||||
|
let focus_in_subscription =
|
||||||
|
cx.on_focus_in(&focus_handle, |diagnostics, cx| diagnostics.focus_in(cx));
|
||||||
|
|
||||||
let excerpts = cx.build_model(|cx| MultiBuffer::new(project_handle.read(cx).replica_id()));
|
let excerpts = cx.build_model(|cx| MultiBuffer::new(project_handle.read(cx).replica_id()));
|
||||||
let editor = cx.build_view(|cx| {
|
let editor = cx.build_view(|cx| {
|
||||||
let mut editor =
|
let mut editor =
|
||||||
|
@ -171,13 +175,17 @@ impl ProjectDiagnosticsEditor {
|
||||||
summary,
|
summary,
|
||||||
workspace,
|
workspace,
|
||||||
excerpts,
|
excerpts,
|
||||||
focus_handle: cx.focus_handle(),
|
focus_handle,
|
||||||
editor,
|
editor,
|
||||||
path_states: Default::default(),
|
path_states: Default::default(),
|
||||||
paths_to_update: HashMap::default(),
|
paths_to_update: HashMap::default(),
|
||||||
include_warnings: ProjectDiagnosticsSettings::get_global(cx).include_warnings,
|
include_warnings: ProjectDiagnosticsSettings::get_global(cx).include_warnings,
|
||||||
current_diagnostics: HashMap::default(),
|
current_diagnostics: HashMap::default(),
|
||||||
_subscriptions: vec![project_event_subscription, editor_event_subscription],
|
_subscriptions: vec![
|
||||||
|
project_event_subscription,
|
||||||
|
editor_event_subscription,
|
||||||
|
focus_in_subscription,
|
||||||
|
],
|
||||||
};
|
};
|
||||||
this.update_excerpts(None, cx);
|
this.update_excerpts(None, cx);
|
||||||
this
|
this
|
||||||
|
@ -202,7 +210,7 @@ impl ProjectDiagnosticsEditor {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_in(&mut self, _: &FocusEvent, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
if self.focus_handle.is_focused(cx) && !self.path_states.is_empty() {
|
if self.focus_handle.is_focused(cx) && !self.path_states.is_empty() {
|
||||||
self.editor.focus_handle(cx).focus(cx)
|
self.editor.focus_handle(cx).focus(cx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -441,6 +441,7 @@ pub trait StatefulInteractiveElement: InteractiveElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO kb do we leave those on an element?
|
||||||
pub trait FocusableElement: InteractiveElement {
|
pub trait FocusableElement: InteractiveElement {
|
||||||
fn focus(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
|
fn focus(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
|
||||||
where
|
where
|
||||||
|
@ -485,51 +486,6 @@ pub trait FocusableElement: InteractiveElement {
|
||||||
}));
|
}));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(mut self, listener: impl Fn(&FocusEvent, &mut WindowContext) + 'static) -> Self
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
self.interactivity()
|
|
||||||
.focus_listeners
|
|
||||||
.push(Box::new(move |focus_handle, event, cx| {
|
|
||||||
let descendant_blurred = event
|
|
||||||
.blurred
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |blurred| focus_handle.contains(blurred, cx));
|
|
||||||
let descendant_focused = event
|
|
||||||
.focused
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |focused| focus_handle.contains(focused, cx));
|
|
||||||
|
|
||||||
if !descendant_blurred && descendant_focused {
|
|
||||||
listener(event, cx)
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_focus_out(mut self, listener: impl Fn(&FocusEvent, &mut WindowContext) + 'static) -> Self
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
self.interactivity()
|
|
||||||
.focus_listeners
|
|
||||||
.push(Box::new(move |focus_handle, event, cx| {
|
|
||||||
let descendant_blurred = event
|
|
||||||
.blurred
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |blurred| focus_handle.contains(blurred, cx));
|
|
||||||
let descendant_focused = event
|
|
||||||
.focused
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |focused| focus_handle.contains(focused, cx));
|
|
||||||
if descendant_blurred && !descendant_focused {
|
|
||||||
listener(event, cx)
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type FocusListeners = SmallVec<[FocusListener; 2]>;
|
pub type FocusListeners = SmallVec<[FocusListener; 2]>;
|
||||||
|
|
|
@ -168,6 +168,7 @@ impl FocusHandle {
|
||||||
self.id.within_focused(cx)
|
self.id.within_focused(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO kb now never used?
|
||||||
/// Obtains whether this handle contains the given handle in the most recently rendered frame.
|
/// Obtains whether this handle contains the given handle in the most recently rendered frame.
|
||||||
pub(crate) fn contains(&self, other: &Self, cx: &WindowContext) -> bool {
|
pub(crate) fn contains(&self, other: &Self, cx: &WindowContext) -> bool {
|
||||||
self.id.contains(other.id, cx)
|
self.id.contains(other.id, cx)
|
||||||
|
|
|
@ -49,8 +49,9 @@ impl Render for FocusStory {
|
||||||
}))
|
}))
|
||||||
.on_focus(cx.listener(|_, _, _| println!("Parent focused")))
|
.on_focus(cx.listener(|_, _, _| println!("Parent focused")))
|
||||||
.on_blur(cx.listener(|_, _, _| println!("Parent blurred")))
|
.on_blur(cx.listener(|_, _, _| println!("Parent blurred")))
|
||||||
.on_focus_in(cx.listener(|_, _, _| println!("Parent focus_in")))
|
// TODO kb todo!() remove?
|
||||||
.on_focus_out(cx.listener(|_, _, _| println!("Parent focus_out")))
|
// .on_focus_in(cx.listener(|_, _, _| println!("Parent focus_in")))
|
||||||
|
// .on_focus_out(cx.listener(|_, _, _| println!("Parent focus_out")))
|
||||||
.on_key_down(cx.listener(|_, event, _| println!("Key down on parent {:?}", event)))
|
.on_key_down(cx.listener(|_, event, _| println!("Key down on parent {:?}", event)))
|
||||||
.on_key_up(cx.listener(|_, event, _| println!("Key up on parent {:?}", event)))
|
.on_key_up(cx.listener(|_, event, _| println!("Key up on parent {:?}", event)))
|
||||||
.size_full()
|
.size_full()
|
||||||
|
@ -70,8 +71,9 @@ impl Render for FocusStory {
|
||||||
.in_focus(|style| style.bg(color_6))
|
.in_focus(|style| style.bg(color_6))
|
||||||
.on_focus(cx.listener(|_, _, _| println!("Child 1 focused")))
|
.on_focus(cx.listener(|_, _, _| println!("Child 1 focused")))
|
||||||
.on_blur(cx.listener(|_, _, _| println!("Child 1 blurred")))
|
.on_blur(cx.listener(|_, _, _| println!("Child 1 blurred")))
|
||||||
.on_focus_in(cx.listener(|_, _, _| println!("Child 1 focus_in")))
|
// TODO kb todo!() remove?
|
||||||
.on_focus_out(cx.listener(|_, _, _| println!("Child 1 focus_out")))
|
// .on_focus_in(cx.listener(|_, _, _| println!("Child 1 focus_in")))
|
||||||
|
// .on_focus_out(cx.listener(|_, _, _| println!("Child 1 focus_out")))
|
||||||
.on_key_down(
|
.on_key_down(
|
||||||
cx.listener(|_, event, _| println!("Key down on child 1 {:?}", event)),
|
cx.listener(|_, event, _| println!("Key down on child 1 {:?}", event)),
|
||||||
)
|
)
|
||||||
|
@ -90,8 +92,9 @@ impl Render for FocusStory {
|
||||||
.bg(color_4)
|
.bg(color_4)
|
||||||
.on_focus(cx.listener(|_, _, _| println!("Child 2 focused")))
|
.on_focus(cx.listener(|_, _, _| println!("Child 2 focused")))
|
||||||
.on_blur(cx.listener(|_, _, _| println!("Child 2 blurred")))
|
.on_blur(cx.listener(|_, _, _| println!("Child 2 blurred")))
|
||||||
.on_focus_in(cx.listener(|_, _, _| println!("Child 2 focus_in")))
|
// TODO kb todo!() remove?
|
||||||
.on_focus_out(cx.listener(|_, _, _| println!("Child 2 focus_out")))
|
// .on_focus_in(cx.listener(|_, _, _| println!("Child 2 focus_in")))
|
||||||
|
// .on_focus_out(cx.listener(|_, _, _| println!("Child 2 focus_out")))
|
||||||
.on_key_down(
|
.on_key_down(
|
||||||
cx.listener(|_, event, _| println!("Key down on child 2 {:?}", event)),
|
cx.listener(|_, event, _| println!("Key down on child 2 {:?}", event)),
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,9 +10,8 @@ pub mod terminal_panel;
|
||||||
use editor::{scroll::autoscroll::Autoscroll, Editor};
|
use editor::{scroll::autoscroll::Autoscroll, Editor};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, impl_actions, overlay, AnyElement, AppContext, DismissEvent, Div, EventEmitter,
|
div, impl_actions, overlay, AnyElement, AppContext, DismissEvent, Div, EventEmitter,
|
||||||
FocusEvent, FocusHandle, Focusable, FocusableElement, FocusableView, KeyContext, KeyDownEvent,
|
FocusHandle, Focusable, FocusableView, KeyContext, KeyDownEvent, Keystroke, Model, MouseButton,
|
||||||
Keystroke, Model, MouseButton, MouseDownEvent, Pixels, Render, Styled, Subscription, Task,
|
MouseDownEvent, Pixels, Render, Styled, Subscription, Task, View, VisualContext, WeakView,
|
||||||
View, VisualContext, WeakView,
|
|
||||||
};
|
};
|
||||||
use language::Bias;
|
use language::Bias;
|
||||||
use persistence::TERMINAL_DB;
|
use persistence::TERMINAL_DB;
|
||||||
|
@ -263,19 +262,13 @@ impl TerminalView {
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
let focus = cx.focus_handle();
|
let focus_handle = cx.focus_handle();
|
||||||
// let focus_in = cx.on_focus_in(&focus, |this, cx| {
|
let focus_in = cx.on_focus_in(&focus_handle, |terminal_view, cx| {
|
||||||
// this.has_new_content = false;
|
terminal_view.focus_in(cx);
|
||||||
// this.terminal.read(cx).focus_in();
|
});
|
||||||
// this.blink_cursors(this.blink_epoch, cx);
|
let focus_out = cx.on_focus_out(&focus_handle, |terminal_view, cx| {
|
||||||
// cx.notify();
|
terminal_view.focus_out(cx);
|
||||||
// });
|
});
|
||||||
// let focus_out = cx.on_focus_out(&focus, |this, cx| {
|
|
||||||
// this.terminal.update(cx, |terminal, _| {
|
|
||||||
// terminal.focus_out();
|
|
||||||
// });
|
|
||||||
// cx.notify();
|
|
||||||
// });
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
terminal,
|
terminal,
|
||||||
|
@ -289,7 +282,7 @@ impl TerminalView {
|
||||||
blink_epoch: 0,
|
blink_epoch: 0,
|
||||||
can_navigate_to_selected_word: false,
|
can_navigate_to_selected_word: false,
|
||||||
workspace_id,
|
workspace_id,
|
||||||
_subscriptions: vec![/*focus_in, focus_out*/],
|
_subscriptions: vec![focus_in, focus_out],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,14 +607,14 @@ impl TerminalView {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_in(&mut self, event: &FocusEvent, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
self.has_new_content = false;
|
self.has_new_content = false;
|
||||||
self.terminal.read(cx).focus_in();
|
self.terminal.read(cx).focus_in();
|
||||||
self.blink_cursors(self.blink_epoch, cx);
|
self.blink_cursors(self.blink_epoch, cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_out(&mut self, event: &FocusEvent, cx: &mut ViewContext<Self>) {
|
fn focus_out(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
self.terminal.update(cx, |terminal, _| {
|
self.terminal.update(cx, |terminal, _| {
|
||||||
terminal.focus_out();
|
terminal.focus_out();
|
||||||
});
|
});
|
||||||
|
@ -650,8 +643,6 @@ impl Render for TerminalView {
|
||||||
.on_action(cx.listener(TerminalView::clear))
|
.on_action(cx.listener(TerminalView::clear))
|
||||||
.on_action(cx.listener(TerminalView::show_character_palette))
|
.on_action(cx.listener(TerminalView::show_character_palette))
|
||||||
.on_action(cx.listener(TerminalView::select_all))
|
.on_action(cx.listener(TerminalView::select_all))
|
||||||
.on_focus_in(cx.listener(Self::focus_in))
|
|
||||||
.on_focus_out(cx.listener(Self::focus_out))
|
|
||||||
.on_key_down(cx.listener(Self::key_down))
|
.on_key_down(cx.listener(Self::key_down))
|
||||||
.on_mouse_down(
|
.on_mouse_down(
|
||||||
MouseButton::Right,
|
MouseButton::Right,
|
||||||
|
|
Loading…
Reference in a new issue