git.lucas.co / cce-mail
mail client (IMAP/SMTP)
git clone https://git.lucas.co/cce-mail.git

commit2f918d9ec1222b3d7c66ddcb8bdab0b1fdf0c62f
parentc58048c538
authorLucas Galante <[email protected]>
date2026-08-14 13:55
fix: a scrollbar press no longer also clicks the row behind it

Rows span x 10..310 and the scrollbar strip sits at ~294..310, so they overlap. The
press went to `email_list.press()` (which consumes it for a thumb grab or track jump)
and then fell through to the per-row dispatch loop anyway, so grabbing the thumb
press+released the row underneath and fired SelectEmail — opening a message the user
never clicked.

A track jump was harmless by accident: the rects move between press and release, so
Button's in-rect release check cancelled the click. A thumb grab, which does not move
the rect under the cursor, was not.

The row loops are now skipped when the scrollbar consumed the press. Release is
unaffected, so an in-flight drag still ends normally.

Live-verified: select the first message, then press the scrollbar at the third
message's y — selection and reading pane stay on the first message.

Co-Authored-By: Claude Opus 5 <[email protected]>

 src/main.rs | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/main.rs b/src/main.rs
index c59adb6..0dc82db 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2563,6 +2563,11 @@ impl Application for ClearEmailApp {
                 }
             }
 
+            // The scrollbar strip sits inside the row rects (rows span x 10..310, the strip
+            // ~294..310), so a press the scrollbar consumed must not also reach the row
+            // underneath it — grabbing the thumb used to press+release the row behind it and
+            // fire SelectEmail.
+            let mut scrollbar_took_press = false;
             if button == MouseButton::Left {
                 let handled = match state {
                     ElementState::Pressed => self.email_list.press(px, py),
@@ -2570,11 +2575,16 @@ impl Application for ClearEmailApp {
                 };
                 if handled {
                     changed = true;
+                    if state == ElementState::Pressed {
+                        scrollbar_took_press = true;
+                    }
                 }
             }
 
 
-            if self.current_folder == Folder::Accounts {
+            if scrollbar_took_press {
+                // fall through to the rest of the handler, but not to the rows
+            } else if self.current_folder == Folder::Accounts {
                 for (idx, _) in self.accounts.iter().enumerate() {
                     if idx < self.email_buttons.len() {
                         let btn = &mut self.email_buttons[idx];