Pointer
The pointer is the mouse, or a touchpad acting as one.
Entering, moving and leaving
| Event | Meaning |
|---|---|
:pointer-enter |
The pointer came into the window. |
:pointer-motion |
The pointer moved over the window. |
:pointer-leave |
The pointer left the window. |
All pointer events go to the window under the pointer, between its
:pointer-enter and its :pointer-leave. event-x and event-y are the
pointer's position at the time of the event:
- in the window's units, the same units as
window-size, not pixels; - relative to the window's top left, with y growing downwards;
- as
single-floats, with fractions: a precise mouse or a scaled display gives positions between whole units.
The window does not know where it is on the screen, so there are no screen coordinates. See Concepts.
To turn a position into pixels, for picking in a framebuffer, multiply by the window's scale:
(let ((scale (win:window-scale window)))
(values (floor (* (win:event-x event) scale))
(floor (* (win:event-y event) scale))))
:pointer-leave reports where the pointer was last seen in the window.
A :pointer-motion event also says how far the pointer moved since the
last motion, event-dx and event-dy, in the window's units. While the
window captures the pointer, event-x and event-y stay put and
event-dx and event-dy are the device's own motion; see
Cursors and Pointer Modes.
Buttons
| Event | Meaning |
|---|---|
:button-press |
A button went down. |
:button-release |
A button came up. |
event-button is a button:
| Button | Meaning |
|---|---|
:left |
The primary button. |
:right |
The secondary button. |
:middle |
The middle button, or pressing the wheel. |
:back |
The side button for going back. |
:forward |
The side button for going forward. |
| an integer | Any other button, by the platform's number. On Linux, the evdev button code. |
Button events carry event-x and event-y too, so a click needs no
separate motion event. Left-handed settings swap the buttons before
cl-windowing sees them: :left is always the primary button.
A press inside a window and a release outside it: both go to the window, because the window system keeps the pointer with the window while a button is held, on Wayland and on Windows alike.
(case (win:event-type event)
(:button-press
(when (eq (win:event-button event) :left)
(start-drag (win:event-x event) (win:event-y event))))
(:pointer-motion
(when *dragging*
(drag-to (win:event-x event) (win:event-y event))))
(:button-release
(when (eq (win:event-button event) :left)
(end-drag))))
Scrolling
A :scroll event says how far to scroll, in steps:
event-scroll-y: positive down, negative up;event-scroll-x: positive right, negative left.
Both can be non-zero in one event, as when a touchpad scrolls diagonally.
| Device | Steps |
|---|---|
| A wheel with notches | 1.0 per notch. |
| A high-resolution wheel | Fractions of a notch, such as 0.25, that add up to 1.0 per notch. |
| A touchpad, or anything that scrolls continuously | 1.0 per 10 units of finger movement. |
So a program that scrolls a list by three lines per notch scrolls by
(* 3 (win:event-scroll-y event)) lines, and that works for touchpads too.
The user's settings, such as natural scrolling, are applied by the platform before cl-windowing sees the scroll. Scroll events carry the pointer's position and the modifiers held, so Control+wheel can zoom at the pointer.
Modifiers
Every pointer event carries the modifiers in effect:
(when (and (eq (win:event-type event) :button-press)
(win:event-modifier-p event :shift))
(extend-selection (win:event-x event) (win:event-y event)))
See Keyboard.
The cursor and holding the pointer
Each window sets the pointer's look over it with window-cursor, and holds
the pointer, confined or captured for a game's camera, with
window-pointer-mode. See
Cursors and Pointer Modes.
Not supported yet
- Touchscreens and drawing tablets as such. They may still act as a pointer, depending on the platform.
On Wayland
Input comes from the compositor's first seat. :pointer is in
window-system-capabilities while that seat has a pointer. Pointer events
are gathered in the protocol's frames, version 5 and later, so each frame
gives at most one :scroll event with both axes.
On Windows
:pointer is in window-system-capabilities while a mouse is present. A
wheel notch is 1.0, and the finer steps of precise wheels and touchpads
come as fractions of it.