git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commit56e0f713aa4c87d723dbe8460531b7ec8357bb91
parentc9d2f53e70
authorLucas Galante <[email protected]>
date2026-07-31 12:30
feat: ColorSelector opens the picker at the control (place-next hint)

Before spawning cce-color-editor, query the compositor's
pointer-location (the pointer is on the swatch that was just clicked)
and register a one-shot `place-next` hint so the picker maps next to
the control instead of its remembered position. Best-effort: on a
non-cce compositor both IPC calls simply fail and the spawn proceeds
unchanged.

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

 src/widget/input/color_selector.rs | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/src/widget/input/color_selector.rs b/src/widget/input/color_selector.rs
index 469b7d8..5428aaa 100644
--- a/src/widget/input/color_selector.rs
+++ b/src/widget/input/color_selector.rs
@@ -462,6 +462,32 @@ impl Input for ColorSelector {
                 self.command.clone()
             };
 
+            // Ask the compositor to open the picker at this control instead of
+            // its remembered position: the pointer is on the swatch right now,
+            // so its location IS the control's location. One-shot, best-effort
+            // (`place-next` consumed at the picker's map; ignored off-cce).
+            if let Ok(reply) = crate::ipc::send_command("cce", "pointer-location") {
+                let mut px = None;
+                let mut py = None;
+                for tok in reply.split_whitespace() {
+                    if let Some(v) = tok.strip_prefix("x=") {
+                        px = v.parse::<f64>().ok();
+                    } else if let Some(v) = tok.strip_prefix("y=") {
+                        py = v.parse::<f64>().ok();
+                    }
+                }
+                if let (Some(x), Some(y)) = (px, py) {
+                    let app_id = std::path::Path::new(&self.command)
+                        .file_name()
+                        .map(|n| n.to_string_lossy().into_owned())
+                        .unwrap_or_else(|| self.command.clone());
+                    let _ = crate::ipc::send_command(
+                        "cce",
+                        &format!("place-next {} {:.0} {:.0}", app_id, x, y),
+                    );
+                }
+            }
+
             let mut cmd = std::process::Command::new(&cmd_path);
             cmd.arg(&hex);
             if self.with_alpha {