Hi,

A few days ago I was asked to find a way to change the mouse cursor in
a clutter Stage via pyclutter.
As there is no API for this in clutter, and it didn't seems possible
to retrieve X display and X window objects in pyclutter.

I came up with a patch for clutter 1.6.16 and pyclutter.
I only added the X11 backend functions.

Any feedback is appreciated.

Is there an other way to do this without modifying clutter source code ?
(Hiding the cursor and put a Texture where it should be is not a
viable option for me.)


Regards,
Yann Le Hir
diff -r clutter-1.6.16/clutter/clutter-stage.c clutter-1.6.16_modified/clutter/clutter-stage.c
150a151
>   guint cursor_type            : 1;
170a172
>   PROP_CURSOR_TYPE,
1108a1111,1114
>     case PROP_CURSOR_TYPE:
>       clutter_stage_set_cursor(stage, g_value_get_int(value));
>       break;
> 
1176a1183,1186
>     case PROP_CURSOR_TYPE:
>       g_value_set_int (value, priv->cursor_type);
>       break;
> 
1347a1358,1371
> 
>   /**
>    * ClutterStage:cursor-visible:
>    *
>    * Whether the mouse pointer should be visible
>    */
>   pspec = g_param_spec_boolean ("cursor-type",
>                                 P_("Cursor Type"),
>                                 P_("Mouse pointer type on the main stage"),
>                                 TRUE,
>                                 CLUTTER_PARAM_READWRITE);
>   g_object_class_install_property (gobject_class,
>                                    PROP_CURSOR_TYPE,
>                                    pspec);
2127a2152,2182
>         }
>     }
> }
> 
> /**
>  * clutter_stage_set_cursor:
>  * @stage: a #ClutterStage
>  * @cursor_type: The id of the cursor to display
>  *
>  * Change the cursor on the stage window
>  */
> void
> clutter_stage_set_cursor (ClutterStage *stage, gint cursor_type)
> {
>   ClutterStagePrivate *priv;
> 
>   g_return_if_fail (CLUTTER_IS_STAGE (stage));
> 
>   priv = stage->priv;
>   if (priv->is_cursor_visible)
>     {
>       ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
>       ClutterStageWindowIface *iface;
> 
>       iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
>       if (iface->set_cursor)
>         {
>           priv->cursor_type = cursor_type;
>           iface->set_cursor (impl, cursor_type);
> 
>           g_object_notify (G_OBJECT (stage), "cursor-type");
diff -r clutter-1.6.16/clutter/clutter-stage.h clutter-1.6.16_modified/clutter/clutter-stage.h
205a206
> void          clutter_stage_set_cursor       (ClutterStage       *stage, gint cursor);
diff -r clutter-1.6.16/clutter/clutter-stage-window.c clutter-1.6.16_modified/clutter/clutter-stage-window.c
49a50,59
> _clutter_stage_window_set_cursor (ClutterStageWindow *window,
>                                   gint                cursor)
> {
>   CLUTTER_STAGE_WINDOW_GET_IFACE (window)->set_cursor (window,
>                                                        cursor);
> }
> 
> 
> 
> void
diff -r clutter-1.6.16/clutter/clutter-stage-window.h clutter-1.6.16_modified/clutter/clutter-stage-window.h
43a44,46
>   void          (* set_cursor)            (ClutterStageWindow *stage_window,
>                                            int                 cursor);
> 
82a86,88
> void          _clutter_stage_window_set_cursor         (ClutterStageWindow *window,
>                                                         int                 cursor);
> 
diff -r clutter-1.6.16/clutter/x11/clutter-stage-x11.c clutter-1.6.16_modified/clutter/x11/clutter-stage-x11.c
373a374,393
> static inline void
> set_cursor (ClutterStageX11 *stage_x11, gint type)
> {
>   ClutterBackendX11 *backend_x11 = stage_x11->backend;
> 
>   if (stage_x11->xwin == None)
>     return;
> 
>   CLUTTER_NOTE (BACKEND, "setting cursor ('%d') over stage window (%u)",
>                 (int) type,
>                 (unsigned int) stage_x11->xwin);
> 
>       Cursor xcursor;
>       xcursor = XCreateFontCursor (backend_x11->xdpy,
>                                    type);
>       XDefineCursor (backend_x11->xdpy,
>                      stage_x11->xwin,
>                      xcursor);
> }
> 
559a580,589
> clutter_stage_x11_set_cursor (ClutterStageWindow *stage_window,
>                               gint            type)
> {
>   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
>   stage_x11->cursor_type = type;
>   set_cursor (stage_x11, type);
> }
> 
> 
> static void
751a782
>   iface->set_cursor = clutter_stage_x11_set_cursor;
diff -r clutter-1.6.16/clutter/x11/clutter-stage-x11.h clutter-1.6.16_modified/clutter/x11/clutter-stage-x11.h
71a72
>   gint  cursor_type          : 1;
73a75
> 

diff --git a/clutter/clutter-base.defs b/clutter/clutter-base.defs
index 84fc1e7..d6d7002 100644
--- a/clutter/clutter-base.defs
+++ b/clutter/clutter-base.defs
@@ -5846,6 +5846,18 @@
   (return-type "gboolean")
 )
 
+(define-method set_cursor
+  (of-object "ClutterStage")
+  (c-name "clutter_stage_set_cursor")
+  (docstring
+  "Change the cursor on the stage window\n"
+  )
+  (return-type "none")
+  (parameters
+    '("guint" "cursor_type")
+  )
+)
+
 (define-method show_cursor
   (of-object "ClutterStage")
   (c-name "clutter_stage_show_cursor")

_______________________________________________
clutter-app-devel-list mailing list
[email protected]
http://lists.clutter-project.org/listinfo/clutter-app-devel-list

Reply via email to