Skip to content

Mouse Cursors

Sergii Stoian edited this page Jun 26, 2018 · 1 revision

Mouse cursors

There are several ways to set mouse cursor:

  1. Using builtin cursor names - call XCreateFontCursor() with predefined name (id) of cursor as second parameter. Cursor names defined in /usr/include/X11/cursorfont.h and start with “XC_” prefix. Used by X11 applications to set cursor image for specific operation.
  2. Using Xorg extension Xcursor. Xcursor provides number of functions to get cusors from cursor theme set. For example: XcursorLibraryLoadCursor() function provides ability to load and return cursor by its file name in current cursor theme. So as addition to method #1 that handles limited number of cursor names, Xcursor let handle arbitrary cursor names.
  3. Using NSCursor class methods that returns standard cursors. Used by AppKit applications that doesn’t have its own cursors and want to use standard ones.
  4. Using NSCursor method -initWithImage:hotSpot:. Should be ssed by AppKit applications that have its own cursors and want to set cursors for specific actions.

    Xcursor extension protocol has no rules for naming and using mouse cursors. Freedesktop’s cursor conventions specification quite scarce and doesn’t cover all names used in modern desktop environments.

    This document aimed to gather information about mouse cursor in various aspects and define some rules for NEXTSPACE applications. While defining rules several important mouse cursor usage contexts were taken into account:

    • X11 applications (Xorg, GTK+, Qt, etc.)
    • Window manager
    • AppKit (GNUstep) applications

    For X11 cursor names I use Adwaita cursor theme as a “de facto” standard.

NSCursor class methods

Cursors returned by NSCursor are inteded to be used by AppKit applications. Application’s cursor should be different in look from cursors of Workspace for similar actions. Such actions are: resizing (NSSplitView vs. windows), drag and drop (copying files vs. file operations in Workspace).

Basically, all sb_* X11 cursors are used by applications (actually it differs from application to application but it’s application scope of responsibility). So we can use them for NXCursor methods. Other resising cursors used by Workspace’s window manager must be a custom cursor images packaged with Workspace or included in Xorg xursor theme (see “Workspace” section below).

“context-menu”, “crossed_circle”, “dnd-copy”, “dnd-link” have no id inside cursorfont.h. That’s why we can’t use XCreateFontCursor function to load cursors in GNUstep X11 Backend’s method -standardcursor:: (XGServerWindow.m). We need to load them as images and create cursor via -imagecursor::: method (XGserverWindow.m).

NSCursor method Image Action
+arrowCursor XCreateFontCursor(dpy, XC_left_ptr)
+IBeamCursor XCreateFontCursor(dpy, XC_xterm)
+crosshairCursor XCreateFontCursor(dpy, XC_crosshair)
+closedHandCursor XCreateFontCursor(dpy, XC_fleur)
+openHandCursor XCreateFontCursor(dpy, XC_hand1)
+pontingHandCursor XCreateFontCursor(dpy, XC_hand2)
+disappearingItemCursor XCreateFontCursor(dpy, XC_pirate)
+resizeDownCursor XCreateFontCursor(dpy, XC_sb_down_arrow)
+reesizeLeftCursor XCreateFontCursor(dpy, XC_sb_left_arrow)
+resizeLeftRightCursor XCreateFontCursor(dpy, sb_h_double_arrow)
+resizeRightCursor XCreateFontCursor(dpy, sb_right_arrow)
+resizeUpCursor XCreateFontCursor(dpy, sb_up_arrow)
+resizeUpDownCursor XCreateFontCursor(dpy, sb_v_double_arrow)
+contextualMenuCursor GUI: contextualMenuCursor.tiff
+operationNotAllowedCursor GUI: operationNotAllowedCursor.tiff
+dragCopyCursor GUI: dragCopyCursor.tiff
+dragLinkCursor GUI: dragLinkCursor.tiff

Workspace

Key-Value pairs specified in a table below are defaults settings of WindowMaker (defaults file: ~/Library/Preferences/.WindowMaker/WindowMaker).

Note: several new settings were added against upstream version of WindowMaker: UpResizeCursor, DownResizeCursor, LeftResizeCursor. RightResizeCursor. Another addition to WindowMaker is new type of cursor - “library”. It uses method #2 described in the beggining of this document (XcursorLibraryLoadCursor function).

Cursor theme packaged with NXAppKit (Resources/Cusors) has special cursor files for window manager usage covering all new defaults added. These files have wm_ prefix in its file names instead of sb_ prefix. All of these non-standard cursor file names are cofigured to use “library” type in window manager’s defaults file.

As a result Workspace uses resizing cursors (fd_*, bd_* and wm_*) which are not intersect with cursors of applications (sb_*).

Image Key Value
BottomLeftResizeCursor (library, “fd_double_arrow”)
BottomRightResizeCursor (library, “bd_double_arrow”)
TopLeftResizeCursor (library, “bd_double_arrow”)
TopRightResizeCursor (library, “fd_double_arrow”)
HorizontalResizeCursor (library, “wm_h_double_arrow”)
VerticalResizeCursor (library, “wm_v_double_arrow”)
UpResizeCursor (library, “wm_up_arrow”)
DownResizeCursor (library, “wm_down_arrow”)
LeftResizeCursor (library, “wm_left_arrow”)
RightResizeCursor (library, “wm_right_arrow”)
SelectCursor (builtin, cross)
MoveCursor (builtin, fleur)
ArrowCursor, NormalCursor (builtin, “left_ptr”)
QuestionCursor (builtin, “question_arrow”)
WaitCursor (builtin, watch)
TextCursor (builtin, xterm)
ResizeCursor (builtin, sizing)

Drag and Drop

Move operation

Cursor - green arrow - recoloured version of arrow cursor (arrowCursor:). This cursor is set by AppKit on move drag and drop operation.

NSCursor method: no cursor method defined in AppKit (both GNUstep and Cocoa).

Theme file name: “dnd-move”

Copy operation

NSCursor method: - +dragCopyCursor:

Theme file name: “dnd-copy”

Link operation

NSCursor method: +dragLinkCursor:

Theme file name: “dnd-link”

Workspace use the same images as AppKit does.

Grabbing

Some applications need to use some sort of drag and drop: grabbing. It is not a drag and drop by nature (e.g. dragging document or image to scroll visible rectangle).

Application should indicate possibility of such operation by “open hand” cursor (openHandCursor: NSCursor’s method, “hand1” in Adwaita) while mouse is over part of application window that can be grabbed. Clicking and holding mouse button action must change cursor image to “closed hand” (closedHandCursor: method, “grabbing” in Adwaita).

Workspace uses Xorg theme cursor with name “move” (four-side arrows image). Used for dragging windows.

Notes on some mouse cursors

There are some mouse cursors in Adwaita theme which confuse me. Here they are:

  • dnd-none - I guess it’s used by some GNOME or KDE applications. Suppose this cursor means “user drags some object but no action will be taken on drop”. What’s the difference from “drop operation is not allowed” (crossed-circle )? From the user point of view: “I drag the object, what will happen if I release the mouse? Nothing? Okay, what will happen if I see cursor changed to crossed circle? Nothing again? So, why my system has to different mouse cursors for one result?” And forgot to mention “dnd-no-drop” (). It’s confusing. To remove confusion it’s normal to link dnd-none to crossed-circle.
  • cell - what does it mean?
  • circle - what does it mean?
  • dotbox - what does it mean?
  • pointer-move - moving mouse pointer with keyboard?
  • link - why we need another link cursor?

Summary

Adw NS Adwaita file name cursorfont.h
X_cursor XC_X_cursor
watch XC_watch
plus XC_plus
xterm XC_xterm
vertical-text -
cross XC_crosshair
tcross XC_tcross
crossed_circle -
question_arrow XC_question_arrow
dnd-ask -
dnd-copy -
dnd-link -
dnd-move -
dnd-no-drop -
dnd-none -
move XC_fleur
all-scroll -
grabbing -
hand1 XC_hand1
hand2 XC_hand2
left_ptr XC_left_ptr
context-menu -
right_ptr XC_right_ptr
left_ptr_watch -
pointer-move -
link -
circle XC_circle
sb_h_double_arrow XC_sb_h_double_arrow
sb_v_double_arrow XC_sb_v_double_arrow
sb_left_arrow XC_sb_left_arrow
sb_right_arrow XC_sb_right_arrow
sb_up_arrow XC_sb_up_arrow
sb_down_arrow XC_sb_down_arrow
bd_double_arrow -
fd_double_arrow -
bottom_left_corner XC_bottom_left_corner
bottom_right_corner XC_bottom_right_corner
top_left_corner XC_top_left_corner
top_right_corner XC_top_right_corner
top_side XC_top_side
bottom_side XC_bottom_side
left_side XC_left_side
right_side XC_right_side
top_tee XC_top_tee
bottom_tee XC_bottom_tee
right_tee XC_right_tee
left_tee XC_left_tee
ll_angle XC_ll_angle
lr_angle XC_lr_angle
ul_angle XC_ul_angle
ur_angle XC_ur_angle
pencil XC_pencil
zoom-in -
zoom-out -
cell -
dotbox XC_dotbox