git.lucas.co / cce-list
things-to-remember checklist
git clone https://git.lucas.co/cce-list.git

commit0a33a0f08970ca92cb090e183924c0efe6fd5d15
parent4b26f762b1
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-07 10:09
Route clicks and hover to the shared context menu while it is open

A right-click on the switcher or the input box opens cce-ui's shared
context menu, and cce-ui leaves routing to it to the app: no click
outside it closed it, and its rows did nothing. While it is open a press
now goes to the menu first, ahead of the switcher -- a row runs,
anywhere else dismisses -- and the pointer drives its row highlight.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 src/main.rs | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/main.rs b/src/main.rs
index d2f5eff..946b001 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -842,6 +842,14 @@ impl Application for ListApp {
 
     fn handle_pointer_move(&mut self, pos: LogicalPosition, needs_rebuild: &mut bool) {
         self.pointer = Some((pos.x, pos.y));
+        // The shared context menu (the switcher's, the input box's) gets the
+        // pointer to itself while open: its row highlight.
+        if cce_ui::widget::context_menu::is_visible() {
+            if cce_ui::widget::context_menu::cursor_moved(pos.x, pos.y) {
+                *needs_rebuild = true;
+            }
+            return;
+        }
         let ev = Event::PointerMove { x: pos.x, y: pos.y, local_x: pos.x, local_y: pos.y };
         if self.ui_context.propagate_event(&ev, self.switcher.id()) {
             *needs_rebuild = true;
@@ -865,6 +873,20 @@ impl Application for ListApp {
         needs_rebuild: &mut bool,
     ) -> Option<Self::Message> {
         let (px, py) = (pos.x, pos.y);
+
+        // The shared context menu a right-click on the switcher or the input box
+        // opens takes every click while open, ahead even of the switcher: a row
+        // runs, a press anywhere else dismisses it. The toolkit leaves this
+        // routing to the app; without it the menu could not be closed by
+        // clicking outside it, and its rows did nothing.
+        if cce_ui::widget::context_menu::is_visible() {
+            if cce_ui::widget::context_menu::mouse_input(button, state, px, py, Some(&mut self.ui_context)) {
+                *needs_rebuild = true;
+                self.needs_rebuild = true;
+            }
+            return None;
+        }
+
         let ev = Event::MouseButton { button, state, x: px, y: py, local_x: px, local_y: py };
 
         // The switcher routes first: its open menu overlays the rows, so a