popover: Revert defer_to focus on Popover open. (#1571)
Revert #1559 added defer to focus. Removed the behavior of focus back to was focused handle on close Popover, this is not correct for Popover.
This commit is contained in:
parent
f26f01909e
commit
a2c16bfae6
2 changed files with 76 additions and 18 deletions
|
|
@ -9,6 +9,7 @@ use gpui_component::{
|
||||||
divider::Divider,
|
divider::Divider,
|
||||||
h_flex,
|
h_flex,
|
||||||
input::{Input, InputState},
|
input::{Input, InputState},
|
||||||
|
list::{List, ListDelegate, ListItem, ListState},
|
||||||
popover::Popover,
|
popover::Popover,
|
||||||
v_flex,
|
v_flex,
|
||||||
};
|
};
|
||||||
|
|
@ -63,6 +64,48 @@ impl Focusable for Form {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DropdownListDelegate {
|
||||||
|
parent: Entity<PopoverStory>,
|
||||||
|
}
|
||||||
|
impl ListDelegate for DropdownListDelegate {
|
||||||
|
type Item = ListItem;
|
||||||
|
|
||||||
|
fn items_count(&self, _: usize, _: &App) -> usize {
|
||||||
|
10
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_item(
|
||||||
|
&self,
|
||||||
|
ix: gpui_component::IndexPath,
|
||||||
|
_: &mut Window,
|
||||||
|
_: &mut App,
|
||||||
|
) -> Option<Self::Item> {
|
||||||
|
Some(ListItem::new(ix).child(format!("Item {}", ix.row)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_selected_index(
|
||||||
|
&mut self,
|
||||||
|
_: Option<gpui_component::IndexPath>,
|
||||||
|
_: &mut Window,
|
||||||
|
_: &mut Context<gpui_component::list::ListState<Self>>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn confirm(&mut self, _: bool, _: &mut Window, cx: &mut Context<ListState<Self>>) {
|
||||||
|
self.parent.update(cx, |this, cx| {
|
||||||
|
this.list_popover_open = false;
|
||||||
|
cx.notify();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cancel(&mut self, _: &mut Window, cx: &mut Context<ListState<Self>>) {
|
||||||
|
self.parent.update(cx, |this, cx| {
|
||||||
|
this.list_popover_open = false;
|
||||||
|
cx.notify();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EventEmitter<DismissEvent> for Form {}
|
impl EventEmitter<DismissEvent> for Form {}
|
||||||
|
|
||||||
impl Render for Form {
|
impl Render for Form {
|
||||||
|
|
@ -81,7 +124,7 @@ impl Render for Form {
|
||||||
.primary()
|
.primary()
|
||||||
.on_click(cx.listener(move |_, _, _, cx| {
|
.on_click(cx.listener(move |_, _, _, cx| {
|
||||||
parent.update(cx, |this, cx| {
|
parent.update(cx, |this, cx| {
|
||||||
this.form_open = false;
|
this.form_popover_open = false;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
})),
|
})),
|
||||||
|
|
@ -92,7 +135,9 @@ impl Render for Form {
|
||||||
pub struct PopoverStory {
|
pub struct PopoverStory {
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
form: Entity<Form>,
|
form: Entity<Form>,
|
||||||
form_open: bool,
|
list: Entity<ListState<DropdownListDelegate>>,
|
||||||
|
form_popover_open: bool,
|
||||||
|
list_popover_open: bool,
|
||||||
checked: bool,
|
checked: bool,
|
||||||
message: String,
|
message: String,
|
||||||
}
|
}
|
||||||
|
|
@ -118,13 +163,18 @@ impl PopoverStory {
|
||||||
|
|
||||||
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
let form = Form::new(cx.entity(), window, cx);
|
let form = Form::new(cx.entity(), window, cx);
|
||||||
|
let parent = cx.entity();
|
||||||
|
let list = cx
|
||||||
|
.new(|cx| ListState::new(DropdownListDelegate { parent }, window, cx).searchable(true));
|
||||||
|
|
||||||
cx.focus_self(window);
|
cx.focus_self(window);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
form,
|
form,
|
||||||
|
list,
|
||||||
checked: true,
|
checked: true,
|
||||||
form_open: false,
|
form_popover_open: false,
|
||||||
|
list_popover_open: false,
|
||||||
focus_handle: cx.focus_handle(),
|
focus_handle: cx.focus_handle(),
|
||||||
message: "".to_string(),
|
message: "".to_string(),
|
||||||
}
|
}
|
||||||
|
|
@ -201,20 +251,37 @@ impl Render for PopoverStory {
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
section("Popover with Form").child(
|
section("Popover with Form").child(
|
||||||
Popover::new("info-bottom-left")
|
Popover::new("popover-form")
|
||||||
.p_0()
|
.p_0()
|
||||||
.text_sm()
|
.text_sm()
|
||||||
.trigger(Button::new("pop").outline().label("Popup Form"))
|
.trigger(Button::new("pop").outline().label("Popup Form"))
|
||||||
.track_focus(&form.focus_handle(cx))
|
.track_focus(&form.focus_handle(cx))
|
||||||
.open(self.form_open)
|
.open(self.form_popover_open)
|
||||||
.on_open_change(cx.listener(move |this, open, _, cx| {
|
.on_open_change(cx.listener(move |this, open, _, cx| {
|
||||||
println!("Popover form open changed: {}", open);
|
println!("Popover form open changed: {}", open);
|
||||||
this.form_open = *open;
|
this.form_popover_open = *open;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}))
|
}))
|
||||||
.child(form.clone()),
|
.child(form.clone()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.child(
|
||||||
|
section("Popover with List").child(
|
||||||
|
Popover::new("popover-list")
|
||||||
|
.p_0()
|
||||||
|
.text_sm()
|
||||||
|
.open(self.list_popover_open)
|
||||||
|
.on_open_change(cx.listener(move |this, open, _, cx| {
|
||||||
|
this.list_popover_open = *open;
|
||||||
|
cx.notify();
|
||||||
|
}))
|
||||||
|
.trigger(Button::new("pop").outline().label("Popup List"))
|
||||||
|
.track_focus(&self.list.focus_handle(cx))
|
||||||
|
.child(List::new(&self.list))
|
||||||
|
.w_64()
|
||||||
|
.h(px(200.)),
|
||||||
|
),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
section("Right click to open Popover").child(
|
section("Right click to open Popover").child(
|
||||||
Popover::new("popover-right-click")
|
Popover::new("popover-right-click")
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,6 @@ pub struct PopoverState {
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
pub(crate) tracked_focus_handle: Option<FocusHandle>,
|
pub(crate) tracked_focus_handle: Option<FocusHandle>,
|
||||||
trigger_bounds: Option<Bounds<Pixels>>,
|
trigger_bounds: Option<Bounds<Pixels>>,
|
||||||
previous_focus: Option<FocusHandle>,
|
|
||||||
open: bool,
|
open: bool,
|
||||||
on_open_change: Option<Rc<dyn Fn(&bool, &mut Window, &mut App)>>,
|
on_open_change: Option<Rc<dyn Fn(&bool, &mut Window, &mut App)>>,
|
||||||
|
|
||||||
|
|
@ -206,7 +205,6 @@ impl PopoverState {
|
||||||
focus_handle: cx.focus_handle(),
|
focus_handle: cx.focus_handle(),
|
||||||
tracked_focus_handle: None,
|
tracked_focus_handle: None,
|
||||||
trigger_bounds: None,
|
trigger_bounds: None,
|
||||||
previous_focus: None,
|
|
||||||
open: default_open,
|
open: default_open,
|
||||||
on_open_change: None,
|
on_open_change: None,
|
||||||
_dismiss_subscription: None,
|
_dismiss_subscription: None,
|
||||||
|
|
@ -236,17 +234,13 @@ impl PopoverState {
|
||||||
self.open = !self.open;
|
self.open = !self.open;
|
||||||
if self.open {
|
if self.open {
|
||||||
let state = cx.entity();
|
let state = cx.entity();
|
||||||
self.previous_focus = window.focused(cx);
|
|
||||||
let focus_handle = if let Some(tracked_focus_handle) = self.tracked_focus_handle.clone()
|
let focus_handle = if let Some(tracked_focus_handle) = self.tracked_focus_handle.clone()
|
||||||
{
|
{
|
||||||
tracked_focus_handle
|
tracked_focus_handle
|
||||||
} else {
|
} else {
|
||||||
self.focus_handle.clone()
|
self.focus_handle.clone()
|
||||||
};
|
};
|
||||||
|
focus_handle.focus(window);
|
||||||
cx.defer_in(window, move |_, window, _| {
|
|
||||||
focus_handle.focus(window);
|
|
||||||
});
|
|
||||||
|
|
||||||
self._dismiss_subscription =
|
self._dismiss_subscription =
|
||||||
Some(
|
Some(
|
||||||
|
|
@ -258,9 +252,6 @@ impl PopoverState {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if let Some(previous_focus) = self.previous_focus.take() {
|
|
||||||
window.focus(&previous_focus);
|
|
||||||
}
|
|
||||||
self._dismiss_subscription = None;
|
self._dismiss_subscription = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -309,7 +300,7 @@ impl RenderOnce for Popover {
|
||||||
});
|
});
|
||||||
|
|
||||||
let open = state.read(cx).open;
|
let open = state.read(cx).open;
|
||||||
let focus_handle = state.focus_handle(cx);
|
let focus_handle = state.read(cx).focus_handle.clone();
|
||||||
let trigger_bounds = state.read(cx).trigger_bounds;
|
let trigger_bounds = state.read(cx).trigger_bounds;
|
||||||
|
|
||||||
let Some(trigger) = self.trigger else {
|
let Some(trigger) = self.trigger else {
|
||||||
|
|
@ -364,8 +355,8 @@ impl RenderOnce for Popover {
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.id("content")
|
.id("content")
|
||||||
.key_context(CONTEXT)
|
|
||||||
.track_focus(&focus_handle)
|
.track_focus(&focus_handle)
|
||||||
|
.key_context(CONTEXT)
|
||||||
.on_action(window.listener_for(&state, PopoverState::on_action_cancel))
|
.on_action(window.listener_for(&state, PopoverState::on_action_cancel))
|
||||||
.size_full()
|
.size_full()
|
||||||
.occlude()
|
.occlude()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue