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

commit9e232295ac6bf0dc9a857ba41fa11e081cb6adb4
parentb63326dd59
authorLucas Galante <[email protected]>
date2026-07-13 13:02
fix(backend): route pointer Enter's position to handle_pointer_move

Enter carried the pointer position but only set the cursor icon — Leave
and Motion both feed handle_pointer_move, so app hover state was stale
from enter until the first in-surface motion. A press in that gap could
misroute: entering a window straight onto cce-files' split divider and
pressing turned into a compositor window move (the movable-backplate
check ran before the app ever saw the divider hover).

Live-verified: boundary-cross onto the files divider + immediate press
(no intervening motion) now drags the divider; suite stays 166/166.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fb2AGNKjfQZxfbxP43fVbC

 src/backend/window_runner.rs | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index 8a7fad3..37c9b4a 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -2275,6 +2275,16 @@ impl<A: Application> PointerHandler for EngineState<A> {
             self.cursor_pos = (lx, ly);
             match &event.kind {
                 PointerEventKind::Enter { .. } => {
+                    // Enter carries the pointer's position but no Motion follows until it
+                    // actually moves — without this the app's hover state is stale from
+                    // enter to first move, and a press in that window can misroute (e.g. a
+                    // divider press falling through to the movable-backplate window drag).
+                    let mut rebuild = false;
+                    self.inner.as_mut().unwrap().handle_pointer_move(LogicalPosition::new(lx, ly), &mut rebuild);
+                    if rebuild {
+                        self.redraw = true;
+                    }
+
                     let is_status_bar = self.inner.as_ref().unwrap().settings().app_id.starts_with("cce-status");
                     let mut cursor_icon = CursorIcon::Default;
                     if !is_status_bar {