Fix focus handle leak (#26090)

This fixes a major performance issue in the current git beta.
This PR also removes the PopoverButton component, which was easy to
misuse.

Release Notes:

- Git Beta: Fix frame drops caused by opening the git panel

---------

Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
This commit is contained in:
Conrad Irwin 2025-03-04 17:50:26 -07:00 committed by GitHub
parent fe18c73a07
commit 674fb7621f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 276 additions and 459 deletions

View file

@ -1,6 +1,6 @@
use gpui::{
AnyElement, AnyView, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
Subscription, Task, WeakEntity,
AnyElement, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, Subscription,
Task, WeakEntity,
};
use picker::{Picker, PickerDelegate};
use project::{
@ -8,7 +8,7 @@ use project::{
Project,
};
use std::sync::Arc;
use ui::{prelude::*, ListItem, ListItemSpacing, PopoverMenu, PopoverMenuHandle, PopoverTrigger};
use ui::{prelude::*, ListItem, ListItemSpacing};
pub struct RepositorySelector {
picker: Entity<Picker<RepositorySelectorDelegate>>,
@ -47,10 +47,6 @@ impl RepositorySelector {
}
}
pub(crate) fn repositories_len(&self, cx: &App) -> usize {
self.picker.read(cx).delegate.repository_entries.len()
}
fn handle_project_git_event(
&mut self,
git_store: &Entity<GitStore>,
@ -82,54 +78,6 @@ impl Render for RepositorySelector {
}
}
#[derive(IntoElement)]
pub struct RepositorySelectorPopoverMenu<T, TT>
where
T: PopoverTrigger + ButtonCommon,
TT: Fn(&mut Window, &mut App) -> AnyView + 'static,
{
repository_selector: Entity<RepositorySelector>,
trigger: T,
tooltip: TT,
handle: Option<PopoverMenuHandle<RepositorySelector>>,
}
impl<T, TT> RepositorySelectorPopoverMenu<T, TT>
where
T: PopoverTrigger + ButtonCommon,
TT: Fn(&mut Window, &mut App) -> AnyView + 'static,
{
pub fn new(repository_selector: Entity<RepositorySelector>, trigger: T, tooltip: TT) -> Self {
Self {
repository_selector,
trigger,
tooltip,
handle: None,
}
}
pub fn with_handle(mut self, handle: PopoverMenuHandle<RepositorySelector>) -> Self {
self.handle = Some(handle);
self
}
}
impl<T, TT> RenderOnce for RepositorySelectorPopoverMenu<T, TT>
where
T: PopoverTrigger + ButtonCommon,
TT: Fn(&mut Window, &mut App) -> AnyView + 'static,
{
fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
let repository_selector = self.repository_selector.clone();
PopoverMenu::new("repository-switcher")
.menu(move |_window, _cx| Some(repository_selector.clone()))
.trigger_with_tooltip(self.trigger, self.tooltip)
.attach(gpui::Corner::BottomLeft)
.when_some(self.handle.clone(), |menu, handle| menu.with_handle(handle))
}
}
pub struct RepositorySelectorDelegate {
project: WeakEntity<Project>,
repository_selector: WeakEntity<RepositorySelector>,