From 1a0e501efddc9f49da47e1e6eea689bd8c4f2d90 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 19 Dec 2012 13:50:58 +0000 Subject: [PATCH] X11: Use XFixes for show/hide cursor This has been disabled since February 2008, on the grounds that XFixes didn't work reliably for hiding cursors. This has almost certainly been fixed then and seems to work entirely reliably across a number of X servers released in the past few years, and is definitely better than a 1x1 black dot for a cursor. Helpfully though, where the spec states that the cursor will be hidden when inside the specified window or one of its children, it actually only uses the window to look up the Screen, and hides the cursor across the entire Screen. So, when using this, we also need to track crossing events. If it's still broken, this needs to be fixed in the X server. https://bugzilla.gnome.org/show_bug.cgi?id=690497 Signed-off-by: Daniel Stone --- clutter/x11/clutter-stage-x11.c | 34 ++++++++++++++++++++++++++++----- clutter/x11/clutter-stage-x11.h | 1 + 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index ffa2fb5b7..685baa524 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -362,18 +362,21 @@ set_cursor_visible (ClutterStageX11 *stage_x11) if (stage_x11->is_cursor_visible) { -#if 0 /* HAVE_XFIXES - seems buggy/unreliable */ - XFixesShowCursor (backend_x11->xdpy, stage_x11->xwin); +#if HAVE_XFIXES + if (stage_x11->cursor_hidden_xfixes) + { + XFixesShowCursor (backend_x11->xdpy, stage_x11->xwin); + stage_x11->cursor_hidden_xfixes = FALSE; + } #else XUndefineCursor (backend_x11->xdpy, stage_x11->xwin); #endif /* HAVE_XFIXES */ } else { -#if 0 /* HAVE_XFIXES - seems buggy/unreliable, check cursor in firefox - * loading page after hiding. - */ +#if HAVE_XFIXES XFixesHideCursor (backend_x11->xdpy, stage_x11->xwin); + stage_x11->cursor_hidden_xfixes = TRUE; #else XColor col; Pixmap pix; @@ -877,6 +880,7 @@ clutter_stage_x11_init (ClutterStageX11 *stage) stage->is_foreign_xwin = FALSE; stage->fullscreening = FALSE; stage->is_cursor_visible = TRUE; + stage->cursor_hidden_xfixes = FALSE; stage->accept_focus = TRUE; stage->title = NULL; @@ -1154,6 +1158,26 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator, } break; + case EnterNotify: +#if HAVE_XFIXES + if (!stage_x11->is_cursor_visible && !stage_x11->cursor_hidden_xfixes) + { + XFixesHideCursor (backend_x11->xdpy, stage_x11->xwin); + stage_x11->cursor_hidden_xfixes = TRUE; + } +#endif + break; + + case LeaveNotify: +#if HAVE_XFIXES + if (stage_x11->cursor_hidden_xfixes) + { + XFixesShowCursor (backend_x11->xdpy, stage_x11->xwin); + stage_x11->cursor_hidden_xfixes = FALSE; + } +#endif + break; + case Expose: { XExposeEvent *expose = (XExposeEvent *) xevent; diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h index 7e0b2448b..c7a7a1b3c 100644 --- a/clutter/x11/clutter-stage-x11.h +++ b/clutter/x11/clutter-stage-x11.h @@ -67,6 +67,7 @@ struct _ClutterStageX11 guint viewport_initialized : 1; guint accept_focus : 1; guint fullscreen_on_realize : 1; + guint cursor_hidden_xfixes : 1; }; struct _ClutterStageX11Class