GNOME Bugzilla – Bug 69436
api for animated cursors
Last modified: 2013-02-03 22:12:04 UTC
It occurred to me that it would be very nice to have an indirection layer between the X-level cursor support offered by gdk and gtk. This layer should offer a much smaller set of reasonable cursors (similar to the ones offered by Win32: Normal Select (normal arrow), Help Select (arrow with ?), Working in Background (arrow with hourglass), Busy (hourglass) Precision Select (crosshair) Text Select (I-beam) Handwriting (Pen) Unavailable (Circle with diagonal) Vertical Resize (double-headed arrow) Horizontal Resize (double-headed arrow) Diagonal Resize 1 (double-headed arrow) Diagonal Resize 2 (double-headed arrow) Move (crosshair with arrow tips) Alternate Select (upwards pointing arrow, similar to vertical resize) Link Select (pointing hand) or Qt3: http://doc.trolltech.com/3.0/cursors.png Ideally these cursors would be identified by stock ids and themable. Looking through the sources, I note that only gtkcurve, gtkentry and gtkcombo explicitly set cursors (and the gtkcombo one is rather pointless), so that themeing cursors would probably have little effect on gtk, unless the root X cursors also gets themed (probably the job of the corresponding control-center applet).
Here is a pointer to the relevant table in the Java look and feel guide: http://java.sun.com/products/jlf/ed2/book/HIG.Behavior.html#44160
In the docs for GdkCursor, I made a list of "reasonable cursors" I thought we should have.
With XRender 0.5 adding XRenderCreateCursor and thus supporting ARGB cursors, this becomes quite a bit more interesting.
Notable candidates for cursor themability are the color picker and dnd cursors.
i would envision the following GDK api additions: GdkCursor* gdk_cursor_new_from_pixbuf (GdkPixbuf *pixbuf, gint x, gint y); GdkCursor* gdk_cursor_new_from_animation (GdkPixbufAnimation *animation, gint x, gint y); On X, these functions should use the X_RenderCreateCursor and X_RenderCreateAnimCursor requests. Implementing these for win32 via LoadCursorFromFile probably needs save support for the ani and ico pixbuf loaders.
Here is a (not very good) fallback implementation. Unfortunately, I can't work on the real thing, since my X is still at RENDER 0.2.
Created attachment 14199 [details] [review] patch
Here is a new patch, containing an Xcursor-based implementation. I didn't implement gdk_cursor_new_from_animation(), since it is not really possible with the current api to extract an array of images and durations from a GdkPixbufAnimation. Therefore, I've implemented gdk_cursor_new_from_pixbufs() to create an animated cursor from an array of pixbufs + delays.
Created attachment 17695 [details] [review] Xcursor-based patch
API comments: * I think a "cursor_new_from_name" type function probably make sense as part of this, but doesn't need to block addition of the new_from_pixbuf() functions. (See http://mail.gnome.org/archives/gtk-devel-list/2003-June/msg00107.html for a couple of random comments) * Would it be a good idea to have some API for figuring out what the cursor theme on the system supports? I can imagine various cases where the fallbacks wouldn't be good enough and you'd need to do something different ... gtkdnd.c for one thing. You'd want: 8-bit vs. 1-bit alpha Full-color vs. monochrome Maximum supported cursor size * Would a GdkCursorFrame structure be better for new_from_pixbufs() rather than the two parallel arrays? If there were 3 arrays, it would be clearly better, 2 arrays, sort of marginal. Patch comments: * You can/should use PKG_CHECK_MODULES for Xcursor * make sure to remove +#define HAVE_XCURSOR 1 * The doc comments about X servers, need to be phrased to allow for the fact that the windowing system might not be X, and other windowing systems might have the different limitations. (But see above for a query API) * In the incredibly picky department, I think if (src[1] > 0x80) would be better as if (src >= 0x80) so you divide the input range into two equal size pieces. * Brackets need fixing/removing in: + if (n_channels == 3 || src[3] > 0x80) { + *md |= 1 << (i % 8); + } * return value for gdk_cursor_new_from_pixbufs() is on the wrong line. Also, probably should have some g_return_val_if_fail() at the entry point. 'GDK_IS_DISPLAY()' and 'n_pixbufs == 0 || pixbufs != NULL' probably.
Additionally... Replace bogus d += i / 8; md += i / 8; by if (i % 8 == 7) d++, md++; or something smarter. Make it... GdkColor fg = { 0, 0, 0, 0 }; GdkColor bg = { 0, 0xffff, 0xffff, 0xffff }; ...and drop the calls to (deprecated) gdk_color_black and gdk_color_white. Since fg is black, src[1] > 0x80 needs to become src[1] < 0x80. Make it... g_return_val_if_fail (0 <= x && (guint)x < width, NULL); g_return_val_if_fail (0 <= y && (guint)y < height, NULL); ...to save a few warnings. Do s/gdk_drawable_unref/g_object_unref/ since the former is deprecated.
That would probably be display functions, right ? gboolean gdk_display_supports_cursor_alpha (GdkDisplay *display); gboolean gdk_display_supports_cursor_color (GdkDisplay *display); void gdk_display_get_max_cursor_size (GdkDisplay *display, gint *width, gint *height); or even void gdk_display_get_cursor_capabilities (GdkDisplay *display, gint *width, gint *height, gboolean *color, gboolean *alpha); CursorFrame structure might be a good idea, then we could make the hotspot per frame as well. My main question regarding the Xcursor configury is whether you think its worth linking Xcursor for two functions or wether we should just use the underlying Xrender functions directly.
Created attachment 17742 [details] [review] next version, still parallel arrays
Created attachment 17743 [details] [review] framified, queryable version
data and mask_data are leaked.
Here is another patch (omitting the configury) which adds gdk_display_get_maximal_cursor_size() and fixes the leak which Morten noticed. I also added some hints about the query functions to the docs of the creation functions.
Created attachment 17817 [details] [review] another patch
Code has been committed, but it's wrong. It's supposed to be if (i % 8 == 7) d++, md++; Note: "7", not "0".
I suggest that a real patch for that would be helpful. It's not easy to see what needs to be changed.
Looks like I bluntly fixed that back in July: 2003-07-11 Morten Welinder <terra@gnome.org> * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixbuf): Fix memory access error. (#69436)
So is this bug all finished and ready to be closed?
No. We've only implemented the basic gdk functionality to support ARGB cursors. In order to get "themable stock cursors", as the bug says, we need a way to obtain cursors by name (see http://www.freedesktop.org/Standards/cursor-spec for a reasonable list of "standard" cursor names) and have the cursors change automatically according to a desktop-wide cursor-theme. Possibly a lot of the icon theme infrastructure could be reused for that.
gtk 2.8 will have gdk_cursor_new_from_name() and gdk_cursor_get_image()
Remaining todo on this bug is - cursor theme change notification - create animated cursors (?)
cursor theme change notification is in principle there now, via the gtk-cursor-theme-name setting.
Retitling for clarity
From what I understand, the problem is that the stock cursors provided by GdkCursorType are bland and boring and at times plain insufficient, so people tend to ship there own cursors with thier apps... resulting in inconsistant cursors across the gnome desktop. Creating a cursor-theme infrastructure is a great first step to address this, but I think... if gtk+ doesnt make any garauntee about what cursor names are valid, and that a default icon theme is at least present... then how can one be theme friendly with cursors ? Is it planned or desirable to include a list of stock cursors in gtk+ ?
I don't think it is necessary to ship cursors with gtk. If anything, we should define a small set of meaningful cursors, give them meaningful names, and document them including hints for proper usage. Those names should then be mapped to suitable platform cursors.
closing old bugs