Table of Contents
Cursors and Pointer Modes
Cursors
Each window has a cursor, the pointer's look while it is over the window, named as CSS names cursors:
(setf (win:window-cursor window) :text) ; an I-beam, over text
(setf (win:window-cursor window) :ew-resize) ; over a divider
(setf (win:window-cursor window) :hidden) ; no cursor at all
(win:window-cursor window) ; => :HIDDEN
It is :default, the arrow, until set, and takes effect at once if the
pointer is over the window. Setting the cursor a window has already costs
nothing, so it may be set on every pointer motion, as the widget under the
pointer changes.
The type cursor lists them all:
| Cursors | For |
|---|---|
:default |
The arrow. |
:text, :vertical-text |
Text that can be selected. |
:pointer |
Links and buttons. |
:wait, :progress |
Busy; busy in the background but still usable. |
:help, :context-menu |
Help, and a menu to open. |
:cell, :crosshair |
Selecting cells or points. |
:alias, :copy, :move, :no-drop, :not-allowed, :grab, :grabbing |
Drag and drop. |
:n-resize, :e-resize, :s-resize, :w-resize, :ne-resize, :nw-resize, :se-resize, :sw-resize |
Resizing by the edge or corner moved. |
:ew-resize, :ns-resize, :nesw-resize, :nwse-resize |
Resizing both ways. |
:col-resize, :row-resize |
Resizing columns and rows. |
:all-scroll, :zoom-in, :zoom-out |
Scrolling and zooming. |
:hidden |
No cursor. |
Where the platform has no image for a cursor, the nearest it has is shown.
- Wayland: the compositor draws the cursor from its name where it
offers cursor-shape-v1. Elsewhere cl-windowing draws it from the user's
cursor theme, named by
$XCURSOR_THEMEand$XCURSOR_SIZEas other toolkits read them, through libwayland-cursor, at the window's scale, and animates animated cursors. A cursor the theme lacks is shown as:default. - Windows: the cursors are the user's system cursors; where Windows has
none for a cursor, the nearest it has is shown, such as the arrow for
:zoom-in.
Pointer modes
A window holds the pointer as its pointer mode says, a pointer-mode:
(setf (win:window-pointer-mode window) :captured) ; a camera follows the mouse
(setf (win:window-pointer-mode window) :confined) ; a strategy game's edge scrolling
(setf (win:window-pointer-mode window) :free) ; as usual, the default
| Mode | The pointer |
|---|---|
:free |
moves as usual. |
:confined |
cannot leave the window. |
:captured |
is hidden and held where it is. Its motion comes as :pointer-motion events whose event-x and event-y stay put and whose event-dx and event-dy are the device's own motion. |
The captured pointer's motion is without the platform's acceleration:
about a unit for each count of the mouse, so a camera turns by event-dx
and event-dy times a sensitivity:
(:pointer-motion
(when (eq (win:window-pointer-mode window) :captured)
(turn-camera (* sensitivity (win:event-dx event))
(* sensitivity (win:event-dy event)))))
A window holds the pointer only while it has the focus and the pointer has come over it, and gives it back while another window or program has the focus. So the mode lasts until it is set again: a game sets it once, as play starts, and again on pausing.
window-system-capabilities includes :pointer-capture where the window
system can hold the pointer. Setting a mode other than :free signals
unsupported-error where it cannot.
- Wayland: the compositor holds the pointer, through pointer-constraints-v1, and the captured pointer's motion comes through relative-pointer-v1. The compositor must offer both.
- Windows: a window keeps the pointer within its client area, or at one
point of it, with
ClipCursor, and the captured pointer's motion is the mouse's raw input.