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 <daniel@fooishbar.org>
This commit is contained in:
Daniel Stone 2012-12-19 13:50:58 +00:00 committed by Emmanuele Bassi
parent 1baefc4807
commit 1a0e501efd
2 changed files with 30 additions and 5 deletions

View File

@ -362,18 +362,21 @@ set_cursor_visible (ClutterStageX11 *stage_x11)
if (stage_x11->is_cursor_visible) if (stage_x11->is_cursor_visible)
{ {
#if 0 /* HAVE_XFIXES - seems buggy/unreliable */ #if HAVE_XFIXES
XFixesShowCursor (backend_x11->xdpy, stage_x11->xwin); if (stage_x11->cursor_hidden_xfixes)
{
XFixesShowCursor (backend_x11->xdpy, stage_x11->xwin);
stage_x11->cursor_hidden_xfixes = FALSE;
}
#else #else
XUndefineCursor (backend_x11->xdpy, stage_x11->xwin); XUndefineCursor (backend_x11->xdpy, stage_x11->xwin);
#endif /* HAVE_XFIXES */ #endif /* HAVE_XFIXES */
} }
else else
{ {
#if 0 /* HAVE_XFIXES - seems buggy/unreliable, check cursor in firefox #if HAVE_XFIXES
* loading page after hiding.
*/
XFixesHideCursor (backend_x11->xdpy, stage_x11->xwin); XFixesHideCursor (backend_x11->xdpy, stage_x11->xwin);
stage_x11->cursor_hidden_xfixes = TRUE;
#else #else
XColor col; XColor col;
Pixmap pix; Pixmap pix;
@ -877,6 +880,7 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
stage->is_foreign_xwin = FALSE; stage->is_foreign_xwin = FALSE;
stage->fullscreening = FALSE; stage->fullscreening = FALSE;
stage->is_cursor_visible = TRUE; stage->is_cursor_visible = TRUE;
stage->cursor_hidden_xfixes = FALSE;
stage->accept_focus = TRUE; stage->accept_focus = TRUE;
stage->title = NULL; stage->title = NULL;
@ -1154,6 +1158,26 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
} }
break; 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: case Expose:
{ {
XExposeEvent *expose = (XExposeEvent *) xevent; XExposeEvent *expose = (XExposeEvent *) xevent;

View File

@ -67,6 +67,7 @@ struct _ClutterStageX11
guint viewport_initialized : 1; guint viewport_initialized : 1;
guint accept_focus : 1; guint accept_focus : 1;
guint fullscreen_on_realize : 1; guint fullscreen_on_realize : 1;
guint cursor_hidden_xfixes : 1;
}; };
struct _ClutterStageX11Class struct _ClutterStageX11Class