Focus back last focus handle when modal, drawer closed. (#145)

This commit is contained in:
Jason Lee 2024-08-14 18:14:59 +08:00 committed by GitHub
parent c9a1bba3c2
commit a36e3e09d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,4 +1,6 @@
use gpui::{div, AnyView, ParentElement as _, Render, Styled, ViewContext, WindowContext}; use gpui::{
div, AnyView, FocusHandle, ParentElement as _, Render, Styled, ViewContext, WindowContext,
};
use std::{ use std::{
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
rc::Rc, rc::Rc,
@ -37,6 +39,7 @@ impl<'a> ContextModal for WindowContext<'a> {
F: Fn(Drawer, &mut WindowContext) -> Drawer + 'static, F: Fn(Drawer, &mut WindowContext) -> Drawer + 'static,
{ {
Root::update_root(self, move |root, cx| { Root::update_root(self, move |root, cx| {
root.previous_focus_handle = cx.focused();
root.active_drawer = Some(Rc::new(build)); root.active_drawer = Some(Rc::new(build));
cx.notify(); cx.notify();
}) })
@ -49,6 +52,7 @@ impl<'a> ContextModal for WindowContext<'a> {
fn close_drawer(&mut self) { fn close_drawer(&mut self) {
Root::update_root(self, |root, cx| { Root::update_root(self, |root, cx| {
root.active_drawer = None; root.active_drawer = None;
root.focus_back(cx);
cx.notify(); cx.notify();
}) })
} }
@ -58,6 +62,7 @@ impl<'a> ContextModal for WindowContext<'a> {
F: Fn(Modal, &mut WindowContext) -> Modal + 'static, F: Fn(Modal, &mut WindowContext) -> Modal + 'static,
{ {
Root::update_root(self, move |root, cx| { Root::update_root(self, move |root, cx| {
root.previous_focus_handle = cx.focused();
root.active_modal = Some(Rc::new(build)); root.active_modal = Some(Rc::new(build));
cx.notify(); cx.notify();
}) })
@ -70,6 +75,7 @@ impl<'a> ContextModal for WindowContext<'a> {
fn close_modal(&mut self) { fn close_modal(&mut self) {
Root::update_root(self, |root, cx| { Root::update_root(self, |root, cx| {
root.active_modal = None; root.active_modal = None;
root.focus_back(cx);
cx.notify(); cx.notify();
}) })
} }
@ -107,17 +113,21 @@ impl<'a, V> ContextModal for ViewContext<'a, V> {
} }
pub struct Root { pub struct Root {
/// Used to store the focus handle of the previus revious view.
/// When the Modal, Drawer closes, we will focus back to the previous view.
previous_focus_handle: Option<FocusHandle>,
active_drawer: Option<Rc<dyn Fn(Drawer, &mut WindowContext) -> Drawer + 'static>>, active_drawer: Option<Rc<dyn Fn(Drawer, &mut WindowContext) -> Drawer + 'static>>,
active_modal: Option<Rc<dyn Fn(Modal, &mut WindowContext) -> Modal + 'static>>, active_modal: Option<Rc<dyn Fn(Modal, &mut WindowContext) -> Modal + 'static>>,
root_view: AnyView, child: AnyView,
} }
impl Root { impl Root {
pub fn new(root_view: AnyView, _: &mut ViewContext<Self>) -> Self { pub fn new(child: AnyView, _: &mut ViewContext<Self>) -> Self {
Self { Self {
previous_focus_handle: None,
active_drawer: None, active_drawer: None,
active_modal: None, active_modal: None,
root_view, child,
} }
} }
@ -143,6 +153,12 @@ impl Root {
root.read(cx) root.read(cx)
} }
fn focus_back(&mut self, cx: &mut WindowContext) {
if let Some(handle) = self.previous_focus_handle.take() {
cx.focus(&handle);
}
}
} }
impl Render for Root { impl Render for Root {
@ -150,6 +166,6 @@ impl Render for Root {
div() div()
.size_full() .size_full()
.text_color(cx.theme().foreground) .text_color(cx.theme().foreground)
.child(self.root_view.clone()) .child(self.child.clone())
} }
} }