-
Notifications
You must be signed in to change notification settings - Fork 69
Mouse Cursors
There are several ways to set mouse cursor:
- 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. - 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. - 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.
- 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.
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 |
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) |
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.
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.
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?
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 |
Copyright (c) Sergii Stoian