When the pointer moves between WINGs child views (e.g. into a text
field), synthesize WME_ENTER/LEAVE events. This triggers the i-beam
cursor change in wtextfield.c which fires on WME_ENTER.
- Track current_buttons bitmask on press/release
- Set u.motion.state = current_mods | current_buttons so WINGs
text fields see WM_BUTTON1_MASK during click-drag selection
- Implement wl_set_cursor via W_SetCursorImageFn hook for i-beam
Update drag_icon_tree position in handle_pointer_motion so the icon
follows the cursor during drag. Use wlr_scene_drag_icon_create for
proper lifecycle. Remove listeners in handle_drag_destroy. Always
forward button releases so drags end correctly.
Three interrelated bugs caused clicks to land in the wrong place when
the compositor spanned multiple outputs (e.g. two 1920x1080 monitors
side by side in nested Wayland mode):
1. real_pointer_update_global() added lo->x to coordinates that were
already in layout space from wlr_cursor_absolute_to_layout_coords,
double-counting the output offset. It also omitted lo->y entirely,
breaking vertical monitor layouts. Fix: read position from
wlr_cursor->x/y which is always authoritative layout-space.
2. real_pointer_handle_motion() accumulated ev->delta into local_x/y
then set pointer_x/y, after which handle_pointer_motion() added
the same delta again -- doubling every relative motion. Fix: let
handle_pointer_motion() be the sole authority; use wlr_cursor_move()
which respects output layout geometry.
3. Pointer devices from nested Wayland outputs (WL-1, WL-2) were never
registered with wlr_cursor via wlr_cursor_attach_input_device() or
mapped to their output via wlr_cursor_map_input_to_output(). Without
this mapping, wlr_cursor_absolute_to_layout_coords treated the 0..1
range as spanning the entire layout (0..3840) instead of the
device's specific output (e.g. 1920..3840 for WL-2). A previous
workaround disabled absolute motion entirely for nested multi-output,
which left only relative deltas that had no concept of which host
window the mouse was in. Fix: register devices with wlr_cursor and
map them to their outputs; remove the early-return.
All pointer paths now follow the same pattern: mutate position via
wlr_cursor_move()/wlr_cursor_warp(), then read back cursor->x/y into
wl_state.pointer_x/y. Manual bounding-box clamping is retained only
for the no-cursor fallback (headless/test mode).