Start on view-level dispatch approach for keyboard events
This commit is contained in:
parent
6e53deb1b2
commit
6e363e464c
22 changed files with 191 additions and 53 deletions
|
@ -397,7 +397,7 @@ impl View for ChatPanel {
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if matches!(
|
if matches!(
|
||||||
*self.rpc.status().borrow(),
|
*self.rpc.status().borrow(),
|
||||||
client::Status::Connected { .. }
|
client::Status::Connected { .. }
|
||||||
|
|
|
@ -36,7 +36,7 @@ impl View for ContactFinder {
|
||||||
ChildView::new(self.picker.clone(), cx).boxed()
|
ChildView::new(self.picker.clone(), cx).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(&self.picker);
|
cx.focus(&self.picker);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1121,13 +1121,13 @@ impl View for ContactList {
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if !self.filter_editor.is_focused(cx) {
|
if !self.filter_editor.is_focused(cx) {
|
||||||
cx.focus(&self.filter_editor);
|
cx.focus(&self.filter_editor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_out(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_out(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if !self.filter_editor.is_focused(cx) {
|
if !self.filter_editor.is_focused(cx) {
|
||||||
cx.emit(Event::Dismissed);
|
cx.emit(Event::Dismissed);
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,7 +160,7 @@ impl View for ContactsPopover {
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
match &self.child {
|
match &self.child {
|
||||||
Child::ContactList(child) => cx.focus(child),
|
Child::ContactList(child) => cx.focus(child),
|
||||||
|
|
|
@ -135,7 +135,7 @@ impl View for CommandPalette {
|
||||||
ChildView::new(self.picker.clone(), cx).boxed()
|
ChildView::new(self.picker.clone(), cx).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(&self.picker);
|
cx.focus(&self.picker);
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl View for ContextMenu {
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
self.reset(cx);
|
self.reset(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ impl View for ProjectDiagnosticsEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if !self.path_states.is_empty() {
|
if !self.path_states.is_empty() {
|
||||||
cx.focus(&self.editor);
|
cx.focus(&self.editor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6477,7 +6477,7 @@ impl View for Editor {
|
||||||
"Editor"
|
"Editor"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
let focused_event = EditorFocused(cx.handle());
|
let focused_event = EditorFocused(cx.handle());
|
||||||
cx.emit_global(focused_event);
|
cx.emit_global(focused_event);
|
||||||
if let Some(rename) = self.pending_rename.as_ref() {
|
if let Some(rename) = self.pending_rename.as_ref() {
|
||||||
|
@ -6498,7 +6498,7 @@ impl View for Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
let blurred_event = EditorBlurred(cx.handle());
|
let blurred_event = EditorBlurred(cx.handle());
|
||||||
cx.emit_global(blurred_event);
|
cx.emit_global(blurred_event);
|
||||||
self.focused = false;
|
self.focused = false;
|
||||||
|
|
|
@ -53,7 +53,7 @@ impl View for FileFinder {
|
||||||
ChildView::new(self.picker.clone(), cx).boxed()
|
ChildView::new(self.picker.clone(), cx).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(&self.picker);
|
cx.focus(&self.picker);
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ impl View for GoToLine {
|
||||||
.named("go to line")
|
.named("go to line")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
cx.focus(&self.line_editor);
|
cx.focus(&self.line_editor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,8 @@ use crate::{
|
||||||
platform::{self, KeyDownEvent, Platform, PromptLevel, WindowOptions},
|
platform::{self, KeyDownEvent, Platform, PromptLevel, WindowOptions},
|
||||||
presenter::Presenter,
|
presenter::Presenter,
|
||||||
util::post_inc,
|
util::post_inc,
|
||||||
Appearance, AssetCache, AssetSource, ClipboardItem, FontCache, InputHandler, MouseButton,
|
Appearance, AssetCache, AssetSource, ClipboardItem, FontCache, InputHandler, KeyUpEvent,
|
||||||
MouseRegionId, PathPromptOptions, TextLayoutCache,
|
ModifiersChangedEvent, MouseButton, MouseRegionId, PathPromptOptions, TextLayoutCache,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Entity: 'static {
|
pub trait Entity: 'static {
|
||||||
|
@ -60,8 +60,18 @@ pub trait Entity: 'static {
|
||||||
pub trait View: Entity + Sized {
|
pub trait View: Entity + Sized {
|
||||||
fn ui_name() -> &'static str;
|
fn ui_name() -> &'static str;
|
||||||
fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox;
|
fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox;
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
|
fn focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
|
||||||
fn on_focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
|
fn focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
|
||||||
|
fn key_down(&mut self, _: &KeyDownEvent, _: &mut ViewContext<Self>) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
fn key_up(&mut self, _: &KeyUpEvent, _: &mut ViewContext<Self>) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
fn modifiers_changed(&mut self, _: &ModifiersChangedEvent, _: &mut ViewContext<Self>) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn keymap_context(&self, _: &AppContext) -> keymap::Context {
|
fn keymap_context(&self, _: &AppContext) -> keymap::Context {
|
||||||
Self::default_keymap_context()
|
Self::default_keymap_context()
|
||||||
}
|
}
|
||||||
|
@ -1297,7 +1307,7 @@ impl MutableAppContext {
|
||||||
) -> impl Iterator<Item = (&'static str, Box<dyn Action>, SmallVec<[&Binding; 1]>)> {
|
) -> impl Iterator<Item = (&'static str, Box<dyn Action>, SmallVec<[&Binding; 1]>)> {
|
||||||
let mut action_types: HashSet<_> = self.global_actions.keys().copied().collect();
|
let mut action_types: HashSet<_> = self.global_actions.keys().copied().collect();
|
||||||
|
|
||||||
for view_id in self.parents(window_id, view_id) {
|
for view_id in self.ancestors(window_id, view_id) {
|
||||||
if let Some(view) = self.views.get(&(window_id, view_id)) {
|
if let Some(view) = self.views.get(&(window_id, view_id)) {
|
||||||
let view_type = view.as_any().type_id();
|
let view_type = view.as_any().type_id();
|
||||||
if let Some(actions) = self.actions.get(&view_type) {
|
if let Some(actions) = self.actions.get(&view_type) {
|
||||||
|
@ -1327,7 +1337,7 @@ impl MutableAppContext {
|
||||||
let action_type = action.as_any().type_id();
|
let action_type = action.as_any().type_id();
|
||||||
if let Some(window_id) = self.cx.platform.key_window_id() {
|
if let Some(window_id) = self.cx.platform.key_window_id() {
|
||||||
if let Some(focused_view_id) = self.focused_view_id(window_id) {
|
if let Some(focused_view_id) = self.focused_view_id(window_id) {
|
||||||
for view_id in self.parents(window_id, focused_view_id) {
|
for view_id in self.ancestors(window_id, focused_view_id) {
|
||||||
if let Some(view) = self.views.get(&(window_id, view_id)) {
|
if let Some(view) = self.views.get(&(window_id, view_id)) {
|
||||||
let view_type = view.as_any().type_id();
|
let view_type = view.as_any().type_id();
|
||||||
if let Some(actions) = self.actions.get(&view_type) {
|
if let Some(actions) = self.actions.get(&view_type) {
|
||||||
|
@ -1376,7 +1386,7 @@ impl MutableAppContext {
|
||||||
mut visit: impl FnMut(usize, bool, &mut MutableAppContext) -> bool,
|
mut visit: impl FnMut(usize, bool, &mut MutableAppContext) -> bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// List of view ids from the leaf to the root of the window
|
// List of view ids from the leaf to the root of the window
|
||||||
let path = self.parents(window_id, view_id).collect::<Vec<_>>();
|
let path = self.ancestors(window_id, view_id).collect::<Vec<_>>();
|
||||||
|
|
||||||
// Walk down from the root to the leaf calling visit with capture_phase = true
|
// Walk down from the root to the leaf calling visit with capture_phase = true
|
||||||
for view_id in path.iter().rev() {
|
for view_id in path.iter().rev() {
|
||||||
|
@ -1397,7 +1407,7 @@ impl MutableAppContext {
|
||||||
|
|
||||||
// Returns an iterator over all of the view ids from the passed view up to the root of the window
|
// Returns an iterator over all of the view ids from the passed view up to the root of the window
|
||||||
// Includes the passed view itself
|
// Includes the passed view itself
|
||||||
fn parents(&self, window_id: usize, mut view_id: usize) -> impl Iterator<Item = usize> + '_ {
|
fn ancestors(&self, window_id: usize, mut view_id: usize) -> impl Iterator<Item = usize> + '_ {
|
||||||
std::iter::once(view_id)
|
std::iter::once(view_id)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(std::iter::from_fn(move || {
|
.chain(std::iter::from_fn(move || {
|
||||||
|
@ -1445,11 +1455,81 @@ impl MutableAppContext {
|
||||||
self.keystroke_matcher.clear_bindings();
|
self.keystroke_matcher.clear_bindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dispatch_key_down(&mut self, window_id: usize, event: &KeyDownEvent) -> bool {
|
||||||
|
if let Some(focused_view_id) = self.focused_view_id(window_id) {
|
||||||
|
for view_id in self
|
||||||
|
.ancestors(window_id, focused_view_id)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
{
|
||||||
|
if let Some(mut view) = self.cx.views.remove(&(window_id, view_id)) {
|
||||||
|
let handled = view.key_down(event, self, window_id, view_id);
|
||||||
|
self.cx.views.insert((window_id, view_id), view);
|
||||||
|
if handled {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::error!("view {} does not exist", view_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dispatch_key_up(&mut self, window_id: usize, event: &KeyUpEvent) -> bool {
|
||||||
|
if let Some(focused_view_id) = self.focused_view_id(window_id) {
|
||||||
|
for view_id in self
|
||||||
|
.ancestors(window_id, focused_view_id)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
{
|
||||||
|
if let Some(mut view) = self.cx.views.remove(&(window_id, view_id)) {
|
||||||
|
let handled = view.key_up(event, self, window_id, view_id);
|
||||||
|
self.cx.views.insert((window_id, view_id), view);
|
||||||
|
if handled {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::error!("view {} does not exist", view_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dispatch_modifiers_changed(
|
||||||
|
&mut self,
|
||||||
|
window_id: usize,
|
||||||
|
event: &ModifiersChangedEvent,
|
||||||
|
) -> bool {
|
||||||
|
if let Some(focused_view_id) = self.focused_view_id(window_id) {
|
||||||
|
for view_id in self
|
||||||
|
.ancestors(window_id, focused_view_id)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
{
|
||||||
|
if let Some(mut view) = self.cx.views.remove(&(window_id, view_id)) {
|
||||||
|
let handled = view.modifiers_changed(event, self, window_id, view_id);
|
||||||
|
self.cx.views.insert((window_id, view_id), view);
|
||||||
|
if handled {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::error!("view {} does not exist", view_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dispatch_keystroke(&mut self, window_id: usize, keystroke: &Keystroke) -> bool {
|
pub fn dispatch_keystroke(&mut self, window_id: usize, keystroke: &Keystroke) -> bool {
|
||||||
let mut pending = false;
|
let mut pending = false;
|
||||||
|
|
||||||
if let Some(focused_view_id) = self.focused_view_id(window_id) {
|
if let Some(focused_view_id) = self.focused_view_id(window_id) {
|
||||||
for view_id in self.parents(window_id, focused_view_id).collect::<Vec<_>>() {
|
for view_id in self
|
||||||
|
.ancestors(window_id, focused_view_id)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
{
|
||||||
let keymap_context = self
|
let keymap_context = self
|
||||||
.cx
|
.cx
|
||||||
.views
|
.views
|
||||||
|
@ -1580,7 +1660,7 @@ impl MutableAppContext {
|
||||||
is_fullscreen: false,
|
is_fullscreen: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
root_view.update(this, |view, cx| view.on_focus_in(cx.handle().into(), cx));
|
root_view.update(this, |view, cx| view.focus_in(cx.handle().into(), cx));
|
||||||
|
|
||||||
let window =
|
let window =
|
||||||
this.cx
|
this.cx
|
||||||
|
@ -1612,7 +1692,7 @@ impl MutableAppContext {
|
||||||
is_fullscreen: false,
|
is_fullscreen: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
root_view.update(this, |view, cx| view.on_focus_in(cx.handle().into(), cx));
|
root_view.update(this, |view, cx| view.focus_in(cx.handle().into(), cx));
|
||||||
|
|
||||||
let status_item = this.cx.platform.add_status_item();
|
let status_item = this.cx.platform.add_status_item();
|
||||||
this.register_platform_window(window_id, status_item);
|
this.register_platform_window(window_id, status_item);
|
||||||
|
@ -2235,12 +2315,12 @@ impl MutableAppContext {
|
||||||
|
|
||||||
//Handle focus
|
//Handle focus
|
||||||
let focused_id = window.focused_view_id?;
|
let focused_id = window.focused_view_id?;
|
||||||
for view_id in this.parents(window_id, focused_id).collect::<Vec<_>>() {
|
for view_id in this.ancestors(window_id, focused_id).collect::<Vec<_>>() {
|
||||||
if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
|
if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
|
||||||
if active {
|
if active {
|
||||||
view.on_focus_in(this, window_id, view_id, focused_id);
|
view.focus_in(this, window_id, view_id, focused_id);
|
||||||
} else {
|
} else {
|
||||||
view.on_focus_out(this, window_id, view_id, focused_id);
|
view.focus_out(this, window_id, view_id, focused_id);
|
||||||
}
|
}
|
||||||
this.cx.views.insert((window_id, view_id), view);
|
this.cx.views.insert((window_id, view_id), view);
|
||||||
}
|
}
|
||||||
|
@ -2272,16 +2352,16 @@ impl MutableAppContext {
|
||||||
});
|
});
|
||||||
|
|
||||||
let blurred_parents = blurred_id
|
let blurred_parents = blurred_id
|
||||||
.map(|blurred_id| this.parents(window_id, blurred_id).collect::<Vec<_>>())
|
.map(|blurred_id| this.ancestors(window_id, blurred_id).collect::<Vec<_>>())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let focused_parents = focused_id
|
let focused_parents = focused_id
|
||||||
.map(|focused_id| this.parents(window_id, focused_id).collect::<Vec<_>>())
|
.map(|focused_id| this.ancestors(window_id, focused_id).collect::<Vec<_>>())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
if let Some(blurred_id) = blurred_id {
|
if let Some(blurred_id) = blurred_id {
|
||||||
for view_id in blurred_parents.iter().copied() {
|
for view_id in blurred_parents.iter().copied() {
|
||||||
if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
|
if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
|
||||||
view.on_focus_out(this, window_id, view_id, blurred_id);
|
view.focus_out(this, window_id, view_id, blurred_id);
|
||||||
this.cx.views.insert((window_id, view_id), view);
|
this.cx.views.insert((window_id, view_id), view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2294,7 +2374,7 @@ impl MutableAppContext {
|
||||||
if let Some(focused_id) = focused_id {
|
if let Some(focused_id) = focused_id {
|
||||||
for view_id in focused_parents {
|
for view_id in focused_parents {
|
||||||
if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
|
if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
|
||||||
view.on_focus_in(this, window_id, view_id, focused_id);
|
view.focus_in(this, window_id, view_id, focused_id);
|
||||||
this.cx.views.insert((window_id, view_id), view);
|
this.cx.views.insert((window_id, view_id), view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2961,20 +3041,41 @@ pub trait AnyView {
|
||||||
) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
|
) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
|
||||||
fn ui_name(&self) -> &'static str;
|
fn ui_name(&self) -> &'static str;
|
||||||
fn render(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox;
|
fn render(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox;
|
||||||
fn on_focus_in(
|
fn focus_in(
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
view_id: usize,
|
view_id: usize,
|
||||||
focused_id: usize,
|
focused_id: usize,
|
||||||
);
|
);
|
||||||
fn on_focus_out(
|
fn focus_out(
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
view_id: usize,
|
view_id: usize,
|
||||||
focused_id: usize,
|
focused_id: usize,
|
||||||
);
|
);
|
||||||
|
fn key_down(
|
||||||
|
&mut self,
|
||||||
|
event: &KeyDownEvent,
|
||||||
|
cx: &mut MutableAppContext,
|
||||||
|
window_id: usize,
|
||||||
|
view_id: usize,
|
||||||
|
) -> bool;
|
||||||
|
fn key_up(
|
||||||
|
&mut self,
|
||||||
|
event: &KeyUpEvent,
|
||||||
|
cx: &mut MutableAppContext,
|
||||||
|
window_id: usize,
|
||||||
|
view_id: usize,
|
||||||
|
) -> bool;
|
||||||
|
fn modifiers_changed(
|
||||||
|
&mut self,
|
||||||
|
event: &ModifiersChangedEvent,
|
||||||
|
cx: &mut MutableAppContext,
|
||||||
|
window_id: usize,
|
||||||
|
view_id: usize,
|
||||||
|
) -> bool;
|
||||||
fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
|
fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
|
||||||
fn debug_json(&self, cx: &AppContext) -> serde_json::Value;
|
fn debug_json(&self, cx: &AppContext) -> serde_json::Value;
|
||||||
|
|
||||||
|
@ -3040,7 +3141,7 @@ where
|
||||||
View::render(self, &mut RenderContext::new(params, cx))
|
View::render(self, &mut RenderContext::new(params, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(
|
fn focus_in(
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
|
@ -3059,10 +3160,10 @@ where
|
||||||
.type_id();
|
.type_id();
|
||||||
AnyViewHandle::new(window_id, focused_id, focused_type, cx.ref_counts.clone())
|
AnyViewHandle::new(window_id, focused_id, focused_type, cx.ref_counts.clone())
|
||||||
};
|
};
|
||||||
View::on_focus_in(self, focused_view_handle, &mut cx);
|
View::focus_in(self, focused_view_handle, &mut cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_out(
|
fn focus_out(
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
|
@ -3081,7 +3182,40 @@ where
|
||||||
.type_id();
|
.type_id();
|
||||||
AnyViewHandle::new(window_id, blurred_id, blurred_type, cx.ref_counts.clone())
|
AnyViewHandle::new(window_id, blurred_id, blurred_type, cx.ref_counts.clone())
|
||||||
};
|
};
|
||||||
View::on_focus_out(self, blurred_view_handle, &mut cx);
|
View::focus_out(self, blurred_view_handle, &mut cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_down(
|
||||||
|
&mut self,
|
||||||
|
event: &KeyDownEvent,
|
||||||
|
cx: &mut MutableAppContext,
|
||||||
|
window_id: usize,
|
||||||
|
view_id: usize,
|
||||||
|
) -> bool {
|
||||||
|
let mut cx = ViewContext::new(cx, window_id, view_id);
|
||||||
|
View::key_down(self, event, &mut cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_up(
|
||||||
|
&mut self,
|
||||||
|
event: &KeyUpEvent,
|
||||||
|
cx: &mut MutableAppContext,
|
||||||
|
window_id: usize,
|
||||||
|
view_id: usize,
|
||||||
|
) -> bool {
|
||||||
|
let mut cx = ViewContext::new(cx, window_id, view_id);
|
||||||
|
View::key_up(self, event, &mut cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn modifiers_changed(
|
||||||
|
&mut self,
|
||||||
|
event: &ModifiersChangedEvent,
|
||||||
|
cx: &mut MutableAppContext,
|
||||||
|
window_id: usize,
|
||||||
|
view_id: usize,
|
||||||
|
) -> bool {
|
||||||
|
let mut cx = ViewContext::new(cx, window_id, view_id);
|
||||||
|
View::modifiers_changed(self, event, &mut cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
|
fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
|
||||||
|
@ -3463,7 +3597,7 @@ impl<'a, T: View> ViewContext<'a, T> {
|
||||||
if self.window_id != view.window_id {
|
if self.window_id != view.window_id {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
self.parents(view.window_id, view.view_id)
|
self.ancestors(view.window_id, view.view_id)
|
||||||
.any(|parent| parent == self.view_id)
|
.any(|parent| parent == self.view_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6354,13 +6488,13 @@ mod tests {
|
||||||
"View"
|
"View"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.handle().id() == focused.id() {
|
if cx.handle().id() == focused.id() {
|
||||||
self.events.lock().push(format!("{} focused", &self.name));
|
self.events.lock().push(format!("{} focused", &self.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.handle().id() == blurred.id() {
|
if cx.handle().id() == blurred.id() {
|
||||||
self.events.lock().push(format!("{} blurred", &self.name));
|
self.events.lock().push(format!("{} blurred", &self.name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,10 +232,16 @@ impl Presenter {
|
||||||
let mut mouse_events = SmallVec::<[_; 2]>::new();
|
let mut mouse_events = SmallVec::<[_; 2]>::new();
|
||||||
let mut notified_views: HashSet<usize> = Default::default();
|
let mut notified_views: HashSet<usize> = Default::default();
|
||||||
|
|
||||||
// 1. Map the platform event into mouse events, which interact with mouse regions.
|
// 1. Handle platform event. Keyboard events get dispatched immediately, while mouse events
|
||||||
|
// get mapped into the mouse-specific MouseEvent type.
|
||||||
// -> These are usually small: [Mouse Down] or [Mouse up, Click] or [Mouse Moved, Mouse Dragged?]
|
// -> These are usually small: [Mouse Down] or [Mouse up, Click] or [Mouse Moved, Mouse Dragged?]
|
||||||
// -> Also updates mouse-related state
|
// -> Also updates mouse-related state
|
||||||
match &event {
|
match &event {
|
||||||
|
Event::KeyDown(e) => return cx.dispatch_key_down(self.window_id, e),
|
||||||
|
Event::KeyUp(e) => return cx.dispatch_key_up(self.window_id, e),
|
||||||
|
Event::ModifiersChanged(e) => {
|
||||||
|
return cx.dispatch_modifiers_changed(self.window_id, e)
|
||||||
|
}
|
||||||
Event::MouseDown(e) => {
|
Event::MouseDown(e) => {
|
||||||
// Click events are weird because they can be fired after a drag event.
|
// Click events are weird because they can be fired after a drag event.
|
||||||
// MDN says that browsers handle this by starting from 'the most
|
// MDN says that browsers handle this by starting from 'the most
|
||||||
|
@ -345,8 +351,6 @@ impl Presenter {
|
||||||
platform_event: e.clone(),
|
platform_event: e.clone(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(position) = event.position() {
|
if let Some(position) = event.position() {
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl View for OutlineView {
|
||||||
ChildView::new(self.picker.clone(), cx).boxed()
|
ChildView::new(self.picker.clone(), cx).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(&self.picker);
|
cx.focus(&self.picker);
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ impl<D: PickerDelegate> View for Picker<D> {
|
||||||
cx
|
cx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(&self.query_editor);
|
cx.focus(&self.query_editor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl View for ProjectSymbolsView {
|
||||||
ChildView::new(self.picker.clone(), cx).boxed()
|
ChildView::new(self.picker.clone(), cx).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(&self.picker);
|
cx.focus(&self.picker);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl View for BufferSearchBar {
|
||||||
"BufferSearchBar"
|
"BufferSearchBar"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(&self.query_editor);
|
cx.focus(&self.query_editor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,7 @@ impl View for ProjectSearchView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
let handle = cx.weak_handle();
|
let handle = cx.weak_handle();
|
||||||
cx.update_global(|state: &mut ActiveSearches, cx| {
|
cx.update_global(|state: &mut ActiveSearches, cx| {
|
||||||
state
|
state
|
||||||
|
|
|
@ -174,7 +174,7 @@ impl View for TerminalContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(self.content.handle());
|
cx.focus(self.content.handle());
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,14 +343,14 @@ impl View for TerminalView {
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, 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 on_focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
self.terminal.update(cx, |terminal, _| {
|
self.terminal.update(cx, |terminal, _| {
|
||||||
terminal.focus_out();
|
terminal.focus_out();
|
||||||
});
|
});
|
||||||
|
|
|
@ -266,7 +266,7 @@ impl View for ThemeSelector {
|
||||||
ChildView::new(self.picker.clone(), cx).boxed()
|
ChildView::new(self.picker.clone(), cx).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(&self.picker);
|
cx.focus(&self.picker);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1485,7 +1485,7 @@ impl View for Pane {
|
||||||
.named("pane")
|
.named("pane")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if let Some(active_item) = self.active_item() {
|
if let Some(active_item) = self.active_item() {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
// Pane was focused directly. We need to either focus a view inside the active item,
|
// Pane was focused directly. We need to either focus a view inside the active item,
|
||||||
|
|
|
@ -2656,7 +2656,7 @@ impl View for Workspace {
|
||||||
.named("workspace")
|
.named("workspace")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(&mut self, view: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, view: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_self_focused() {
|
if cx.is_self_focused() {
|
||||||
cx.focus(&self.active_pane);
|
cx.focus(&self.active_pane);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue