git.lucas.co / cce-fonts
font browser

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

cce-ui leaves routing to its shared context menu to the app, and
cce-fonts never did it: a right-click on the size spinbox opened the
menu, and then no click could close it, nor run its rows. Now, while
it is open, a press goes to the menu first (a row runs, anywhere else
dismisses, nothing beneath also takes it), the pointer drives its row
highlight, and a size pasted from it reaches the preview.

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

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

diff --git a/src/main.rs b/src/main.rs
index 821cbee..814a948 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1183,6 +1183,16 @@ impl Application for TypefaceApp {
         let px = pos.x as f32;
         let py = pos.y as f32;
 
+        // The shared context menu gets the pointer to itself while open (its
+        // row highlight), as it gets the clicks (`handle_mouse_input`).
+        if cce_ui::widget::context_menu::is_visible() {
+            if cce_ui::widget::context_menu::cursor_moved(px, py) {
+                *needs_rebuild = true;
+                self.needs_rebuild = true;
+            }
+            return;
+        }
+
         let old_size = self.preview_box.font_size;
 
         // The dissolved scroll regions: scrollbar-thumb drags and hover tracking.
@@ -1222,6 +1232,24 @@ impl Application for TypefaceApp {
         let px = pos.x as f32;
         let py = pos.y as f32;
 
+        // The toolkit's shared context menu (the size spinbox's, the text boxes')
+        // takes every click while it is open: a row runs its action, a press
+        // anywhere else dismisses it. The toolkit leaves this routing to the app,
+        // and without it the menu could not be closed by clicking outside it.
+        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;
+            }
+            // A size pasted into the spinbox from the menu.
+            let new_size = self.size_spinbox.value as f32;
+            if (new_size - self.preview_box.font_size).abs() > 0.001 {
+                self.preview_box.font_size = new_size;
+                return Some(AppMessage::FontSizeChanged);
+            }
+            return None;
+        }
+
         if state == ElementState::Pressed && button == MouseButton::Left {
             if !self.search_box.hit_test(px, py, &self.ui_context) {
                 self.search_box.unfocus();