git.lucas.co / cce-weather
weather: now, the next 24 hours and the week
git clone https://git.lucas.co/cce-weather.git

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

A right-click on the search 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 -- a row runs, anywhere else dismisses, and a row's edit is
drained like any change to the box -- 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 1e4acf7..2d245a7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -833,6 +833,15 @@ impl Application for WeatherApp {
     }
 
     fn handle_pointer_move(&mut self, pos: LogicalPosition, needs_rebuild: &mut bool) {
+        // The shared context menu (the search 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) {
+                self.needs_rebuild = true;
+                *needs_rebuild = true;
+            }
+            return;
+        }
         let ev = Event::PointerMove { x: pos.x, y: pos.y, local_x: pos.x, local_y: pos.y };
         if self.route(&ev, false) || self.needs_rebuild {
             self.needs_rebuild = true;
@@ -847,6 +856,19 @@ impl Application for WeatherApp {
         pos: LogicalPosition,
         needs_rebuild: &mut bool,
     ) -> Option<Self::Message> {
+        // The shared context menu a right-click on the search box opens takes
+        // every click while open: 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. A row's
+        // edit (Paste, Cut) is drained like any other change to the box.
+        if cce_ui::widget::context_menu::is_visible() {
+            if cce_ui::widget::context_menu::mouse_input(button, state, pos.x, pos.y, Some(&mut self.ui_context)) {
+                self.drain_widget_changes();
+                self.needs_rebuild = true;
+                *needs_rebuild = true;
+            }
+            return None;
+        }
         let ev = Event::MouseButton { button, state, x: pos.x, y: pos.y, local_x: pos.x, local_y: pos.y };
         if self.route(&ev, false) || self.needs_rebuild {
             self.needs_rebuild = true;