Fix non-unique ids passed to MouseEventHandlers

Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
Max Brunsfeld 2022-02-17 09:43:03 -08:00
parent 4a6713aef6
commit d173e4ef3c
5 changed files with 76 additions and 66 deletions

View file

@ -27,6 +27,7 @@ impl ContactsPanel {
1000., 1000.,
{ {
let app_state = app_state.clone(); let app_state = app_state.clone();
let view_id = cx.view_id();
move |ix, cx| { move |ix, cx| {
let user_store = app_state.user_store.read(cx); let user_store = app_state.user_store.read(cx);
let contacts = user_store.contacts().clone(); let contacts = user_store.contacts().clone();
@ -35,6 +36,7 @@ impl ContactsPanel {
&contacts[ix], &contacts[ix],
current_user_id, current_user_id,
app_state.clone(), app_state.clone(),
view_id,
cx, cx,
) )
} }
@ -56,6 +58,7 @@ impl ContactsPanel {
collaborator: &Contact, collaborator: &Contact,
current_user_id: Option<u64>, current_user_id: Option<u64>,
app_state: Arc<AppState>, app_state: Arc<AppState>,
view_id: usize,
cx: &mut LayoutContext, cx: &mut LayoutContext,
) -> ElementBox { ) -> ElementBox {
let theme = &app_state.settings.borrow().theme.contacts_panel; let theme = &app_state.settings.borrow().theme.contacts_panel;
@ -157,7 +160,7 @@ impl ContactsPanel {
let app_state = app_state.clone(); let app_state = app_state.clone();
MouseEventHandler::new::<ContactsPanel, _, _, _>( MouseEventHandler::new::<ContactsPanel, _, _, _>(
project_id as usize, view_id,
cx, cx,
|mouse_state, _| { |mouse_state, _| {
let style = match (project.is_shared, mouse_state.hovered) { let style = match (project.is_shared, mouse_state.hovered) {

View file

@ -523,6 +523,7 @@ impl ContextMenu {
} }
struct CompletionsMenu { struct CompletionsMenu {
editor_id: usize,
id: CompletionId, id: CompletionId,
initial_position: Anchor, initial_position: Anchor,
buffer: ModelHandle<Buffer>, buffer: ModelHandle<Buffer>,
@ -560,6 +561,7 @@ impl CompletionsMenu {
let settings = build_settings(cx); let settings = build_settings(cx);
let completions = self.completions.clone(); let completions = self.completions.clone();
let matches = self.matches.clone(); let matches = self.matches.clone();
let editor_id = self.editor_id;
let selected_item = self.selected_item; let selected_item = self.selected_item;
UniformList::new(self.list.clone(), matches.len(), move |range, items, cx| { UniformList::new(self.list.clone(), matches.len(), move |range, items, cx| {
let settings = build_settings(cx); let settings = build_settings(cx);
@ -569,7 +571,7 @@ impl CompletionsMenu {
let item_ix = start_ix + ix; let item_ix = start_ix + ix;
items.push( items.push(
MouseEventHandler::new::<CompletionTag, _, _, _>( MouseEventHandler::new::<CompletionTag, _, _, _>(
mat.candidate_id, (editor_id, mat.candidate_id),
cx, cx,
|state, _| { |state, _| {
let item_style = if item_ix == selected_item { let item_style = if item_ix == selected_item {
@ -666,6 +668,7 @@ impl CompletionsMenu {
#[derive(Clone)] #[derive(Clone)]
struct CodeActionsMenu { struct CodeActionsMenu {
editor_id: usize,
actions: Arc<[CodeAction]>, actions: Arc<[CodeAction]>,
buffer: ModelHandle<Buffer>, buffer: ModelHandle<Buffer>,
selected_item: usize, selected_item: usize,
@ -702,6 +705,7 @@ impl CodeActionsMenu {
let settings = build_settings(cx); let settings = build_settings(cx);
let actions = self.actions.clone(); let actions = self.actions.clone();
let editor_id = self.editor_id;
let selected_item = self.selected_item; let selected_item = self.selected_item;
let element = let element =
UniformList::new(self.list.clone(), actions.len(), move |range, items, cx| { UniformList::new(self.list.clone(), actions.len(), move |range, items, cx| {
@ -710,21 +714,28 @@ impl CodeActionsMenu {
for (ix, action) in actions[range].iter().enumerate() { for (ix, action) in actions[range].iter().enumerate() {
let item_ix = start_ix + ix; let item_ix = start_ix + ix;
items.push( items.push(
MouseEventHandler::new::<ActionTag, _, _, _>(item_ix, cx, |state, _| { MouseEventHandler::new::<ActionTag, _, _, _>(
let item_style = if item_ix == selected_item { (editor_id, item_ix),
settings.style.autocomplete.selected_item cx,
} else if state.hovered { |state, _| {
settings.style.autocomplete.hovered_item let item_style = if item_ix == selected_item {
} else { settings.style.autocomplete.selected_item
settings.style.autocomplete.item } else if state.hovered {
}; settings.style.autocomplete.hovered_item
} else {
settings.style.autocomplete.item
};
Text::new(action.lsp_action.title.clone(), settings.style.text.clone()) Text::new(
action.lsp_action.title.clone(),
settings.style.text.clone(),
)
.with_soft_wrap(false) .with_soft_wrap(false)
.contained() .contained()
.with_style(item_style) .with_style(item_style)
.boxed() .boxed()
}) },
)
.with_cursor_style(CursorStyle::PointingHand) .with_cursor_style(CursorStyle::PointingHand)
.on_mouse_down(move |cx| { .on_mouse_down(move |cx| {
cx.dispatch_action(ConfirmCodeAction(Some(item_ix))); cx.dispatch_action(ConfirmCodeAction(Some(item_ix)));
@ -1937,6 +1948,7 @@ impl Editor {
} }
let mut menu = CompletionsMenu { let mut menu = CompletionsMenu {
editor_id: this.id(),
id, id,
initial_position: position, initial_position: position,
match_candidates: completions match_candidates: completions
@ -2119,6 +2131,7 @@ impl Editor {
if let Some((buffer, actions)) = this.available_code_actions.clone() { if let Some((buffer, actions)) = this.available_code_actions.clone() {
this.show_context_menu( this.show_context_menu(
ContextMenu::CodeActions(CodeActionsMenu { ContextMenu::CodeActions(CodeActionsMenu {
editor_id: this.handle.id(),
buffer, buffer,
actions, actions,
selected_item: Default::default(), selected_item: Default::default(),

View file

@ -476,58 +476,54 @@ impl ProjectPanel {
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> ElementBox { ) -> ElementBox {
let is_dir = details.is_dir; let is_dir = details.is_dir;
MouseEventHandler::new::<Self, _, _, _>( MouseEventHandler::new::<Self, _, _, _>((cx.view_id(), entry.entry_id), cx, |state, _| {
(entry.worktree_id.to_usize(), entry.entry_id), let style = match (details.is_selected, state.hovered) {
cx, (false, false) => &theme.entry,
|state, _| { (false, true) => &theme.hovered_entry,
let style = match (details.is_selected, state.hovered) { (true, false) => &theme.selected_entry,
(false, false) => &theme.entry, (true, true) => &theme.hovered_selected_entry,
(false, true) => &theme.hovered_entry, };
(true, false) => &theme.selected_entry, Flex::row()
(true, true) => &theme.hovered_selected_entry, .with_child(
}; ConstrainedBox::new(
Flex::row() Align::new(
.with_child( ConstrainedBox::new(if is_dir {
ConstrainedBox::new( if details.is_expanded {
Align::new( Svg::new("icons/disclosure-open.svg")
ConstrainedBox::new(if is_dir { .with_color(style.icon_color)
if details.is_expanded { .boxed()
Svg::new("icons/disclosure-open.svg")
.with_color(style.icon_color)
.boxed()
} else {
Svg::new("icons/disclosure-closed.svg")
.with_color(style.icon_color)
.boxed()
}
} else { } else {
Empty::new().boxed() Svg::new("icons/disclosure-closed.svg")
}) .with_color(style.icon_color)
.with_max_width(style.icon_size) .boxed()
.with_max_height(style.icon_size) }
.boxed(), } else {
) Empty::new().boxed()
})
.with_max_width(style.icon_size)
.with_max_height(style.icon_size)
.boxed(), .boxed(),
) )
.with_width(style.icon_size)
.boxed(), .boxed(),
) )
.with_child( .with_width(style.icon_size)
Label::new(details.filename, style.text.clone()) .boxed(),
.contained() )
.with_margin_left(style.icon_spacing) .with_child(
.aligned() Label::new(details.filename, style.text.clone())
.left() .contained()
.boxed(), .with_margin_left(style.icon_spacing)
) .aligned()
.constrained() .left()
.with_height(theme.entry.height) .boxed(),
.contained() )
.with_style(style.container) .constrained()
.with_padding_left(theme.container.padding.left + details.depth as f32 * 20.) .with_height(theme.entry.height)
.boxed() .contained()
}, .with_style(style.container)
) .with_padding_left(theme.container.padding.left + details.depth as f32 * 20.)
.boxed()
})
.on_click(move |cx| { .on_click(move |cx| {
if is_dir { if is_dir {
cx.dispatch_action(ToggleExpanded(entry)) cx.dispatch_action(ToggleExpanded(entry))

View file

@ -1,8 +1,6 @@
use super::Workspace; use super::Workspace;
use crate::Settings; use crate::Settings;
use gpui::{ use gpui::{action, elements::*, platform::CursorStyle, AnyViewHandle, RenderContext};
action, elements::*, platform::CursorStyle, AnyViewHandle, MutableAppContext, RenderContext,
};
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
pub struct Sidebar { pub struct Sidebar {
@ -126,7 +124,7 @@ impl Sidebar {
pub fn render_active_item( pub fn render_active_item(
&self, &self,
settings: &Settings, settings: &Settings,
cx: &mut MutableAppContext, cx: &mut RenderContext<Workspace>,
) -> Option<ElementBox> { ) -> Option<ElementBox> {
if let Some(active_item) = self.active_item() { if let Some(active_item) = self.active_item() {
let mut container = Flex::row(); let mut container = Flex::row();
@ -159,11 +157,11 @@ impl Sidebar {
fn render_resize_handle( fn render_resize_handle(
&self, &self,
settings: &Settings, settings: &Settings,
mut cx: &mut MutableAppContext, cx: &mut RenderContext<Workspace>,
) -> ElementBox { ) -> ElementBox {
let width = self.width.clone(); let width = self.width.clone();
let side = self.side; let side = self.side;
MouseEventHandler::new::<Self, _, _, _>(self.side.id(), &mut cx, |_, _| { MouseEventHandler::new::<Self, _, _, _>((cx.view_id(), self.side.id()), cx, |_, _| {
Container::new(Empty::new().boxed()) Container::new(Empty::new().boxed())
.with_style(self.theme(settings).resize_handle) .with_style(self.theme(settings).resize_handle)
.boxed() .boxed()

View file

@ -1252,7 +1252,7 @@ impl Workspace {
theme.workspace.titlebar.share_icon_color theme.workspace.titlebar.share_icon_color
}; };
Some( Some(
MouseEventHandler::new::<Share, _, _, _>(0, cx, |_, _| { MouseEventHandler::new::<Share, _, _, _>(cx.view_id(), cx, |_, _| {
Align::new( Align::new(
ConstrainedBox::new( ConstrainedBox::new(
Svg::new("icons/broadcast-24.svg").with_color(color).boxed(), Svg::new("icons/broadcast-24.svg").with_color(color).boxed(),