git.lucas.co / cce-cloud
cloud storage client
git clone https://git.lucas.co/cce-cloud.git

commit3583145513f045ac33bec422656252788f059c63
parente59e53d874
authorLucas Galante <[email protected]>
date2026-08-23 23:02
switcher: keep two-click commit; single click stays everywhere else

The previous commit made every popup activate on any row press. For the
switcher that is too eager: its rows are live windows, so a stray first
click would refocus immediately. It now takes the pre-existing Apps-mode
shape instead — a click on an unselected row only moves the highlight, and
a click on the selected row commits. Apps, Path and Dmenu keep single-click.

Verified in a shadow session end to end: apps popup single click launches
(0.21s); in the switcher the first click on an unselected window row moved
the highlight with the popup still up, and the second click closed it and
switched focus.

 src/main.rs | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index e2062bf..ea4a429 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1919,6 +1919,7 @@ impl PointerHandler for AppState {
                                 st.upload_vertices();
                                 self.redraw = true;
                             } else {
+                                let prev_selected = st.fuzzel.selected;
                                 let changed = {
                                     let ev = cce_ui::widget::Event::MouseButton {
                                         button: cce_ui::widget::MouseButton::Left,
@@ -1933,15 +1934,18 @@ impl PointerHandler for AppState {
                                     st.ui_context.propagate_event(&ev, root)
                                 };
                                 if changed {
-                                    // Any row press activates. This used to gate on
-                                    // `selected == prev_selected` outside Dmenu/switcher
-                                    // mode — click-to-select, click-AGAIN-to-launch — so a
-                                    // single click on an unselected app only moved the
-                                    // highlight, which reads as the click doing nothing.
-                                    // The fuzzel on_event already resolved the press to a
-                                    // really-drawn row (scrollbar and clipped-sliver
-                                    // presses never get here), so the click IS the choice.
-                                    {
+                                    // A single click launches — the fuzzel on_event only
+                                    // reports presses it resolved to a really-drawn row
+                                    // (scrollbar and clipped-sliver presses never get
+                                    // here), so the click IS the choice, exactly as Enter.
+                                    // (The old gate gated Apps/Path on `selected ==
+                                    // prev_selected`, which read as the click doing
+                                    // nothing.) The SWITCHER keeps two-click: its rows are
+                                    // live windows, and focusing one on a stray first
+                                    // click would be destructive — click to inspect the
+                                    // selection, click it again to commit.
+                                    let commit = !st.switcher_mode || st.fuzzel.selected == prev_selected;
+                                    if commit {
                                         if let Some(item) = st.fuzzel.filtered_items.get(st.fuzzel.selected) {
                                             println!("{}", item);
                                             self.selected_item = Some(item.clone());