Remove focus filtering from gpui so all focus events result in focus-in and focus-out calls

Remove pane focused event in favor of focus_in at the workspace level
Added is_child to ViewContext to determine if a given view is a child of the current view
Fix issue where dock would get in a infinite loop when activated after dragging an item out of it
Fix issue where the last focused view in an item was not correctly refocused when a pane is focused after switching active tabs

Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
K Simmons 2022-10-12 15:10:00 -07:00
parent 81a3a22379
commit 1d8717f4de
6 changed files with 249 additions and 131 deletions

View file

@ -1,5 +1,4 @@
/// NOTE: Focus only 'takes' after an update has flushed_effects. Pane sends an event in on_focus_in
/// which the workspace uses to change the activated pane.
/// NOTE: Focus only 'takes' after an update has flushed_effects.
///
/// This may cause issues when you're trying to write tests that use workspace focus to add items at
/// specific locations.
@ -970,7 +969,7 @@ pub struct Workspace {
panes: Vec<ViewHandle<Pane>>,
panes_by_item: HashMap<usize, WeakViewHandle<Pane>>,
active_pane: ViewHandle<Pane>,
last_active_center_pane: Option<ViewHandle<Pane>>,
last_active_center_pane: Option<WeakViewHandle<Pane>>,
status_bar: ViewHandle<StatusBar>,
titlebar_item: Option<AnyViewHandle>,
dock: Dock,
@ -1110,7 +1109,7 @@ impl Workspace {
panes: vec![dock_pane, center_pane.clone()],
panes_by_item: Default::default(),
active_pane: center_pane.clone(),
last_active_center_pane: Some(center_pane.clone()),
last_active_center_pane: Some(center_pane.downgrade()),
status_bar,
titlebar_item: None,
notifications: Default::default(),
@ -1845,7 +1844,7 @@ impl Workspace {
if &pane == self.dock_pane() {
Dock::show(self, cx);
} else {
self.last_active_center_pane = Some(pane.clone());
self.last_active_center_pane = Some(pane.downgrade());
if self.dock.is_anchored_at(DockAnchor::Expanded) {
Dock::hide(self, cx);
}
@ -1876,7 +1875,6 @@ impl Workspace {
}
pane::Event::Remove if !is_dock => self.remove_pane(pane, cx),
pane::Event::Remove if is_dock => Dock::hide(self, cx),
pane::Event::Focused => self.handle_pane_focused(pane, cx),
pane::Event::ActivateItem { local } => {
if *local {
self.unfollow(&pane, cx);
@ -1937,7 +1935,7 @@ impl Workspace {
for removed_item in pane.read(cx).items() {
self.panes_by_item.remove(&removed_item.id());
}
if self.last_active_center_pane == Some(pane) {
if self.last_active_center_pane == Some(pane.downgrade()) {
self.last_active_center_pane = None;
}
@ -2647,9 +2645,17 @@ impl View for Workspace {
.named("workspace")
}
fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
fn on_focus_in(&mut self, view: AnyViewHandle, cx: &mut ViewContext<Self>) {
if cx.is_self_focused() {
cx.focus(&self.active_pane);
} else {
for pane in self.panes() {
let view = view.clone();
if pane.update(cx, |_, cx| cx.is_child(view)) {
self.handle_pane_focused(pane.clone(), cx);
break;
}
}
}
}