-
Notifications
You must be signed in to change notification settings - Fork 536
table: no way to prevent row context menu when right-clicking header #2214
Description
Problem
When using TableDelegate::render_th() with ContextMenuExt to add context menus to column headers, right-clicking a header shows both the row context menu and the header context menu simultaneously.
Root cause
The row context menu is attached to inner_table (in render() at state.rs ~line 1973), which wraps both the header and body. When right-clicking a header cell:
- The
inner_tablecontext menu fires because the header is geometrically inside its bounds - It reads
right_clicked_rowwhich may still beSomefrom a previous row click - The header's own context menu (from
ContextMenuExt) also opens independently - Both menus appear at the same time
The on_mouse_down_out dismiss handler on the row menu doesn't fire because the click is inside inner_table's bounds.
Workaround
I overrode render_header to add on_mouse_down(MouseButton::Right) that clears the row state before menu builders run. However, right_clicked_row is private, so I forked and added:
pub fn clear_right_clicked_row(&mut self) {
self.right_clicked_row = None;
}Suggested fix
Either:
- Expose
clear_right_clicked_row()(or aset_right_clicked_row) as a public method onTableState - Add a
header_context_menu()method toTableDelegate(similar tocontext_menu()for rows) that the framework handles correctly - Window-level context menu tracking so opening any context menu auto-dismisses others
Option 1 is the smallest change. Option 2 is the cleanest API.
Reproduction
impl TableDelegate for MyDelegate {
fn render_th(&mut self, col_ix: usize, _window: &mut Window, cx: &mut Context<TableState<Self>>) -> impl IntoElement {
div()
.id(("th", col_ix))
.child("Header")
.context_menu(|menu, _w, _cx| {
menu.item(PopupMenuItem::new("Header action"))
})
}
fn context_menu(&mut self, row_ix: usize, menu: PopupMenu, ...) -> PopupMenu {
menu.item(PopupMenuItem::new("Row action"))
}
}Steps: Right-click a row → right-click a column header → two menus appear.