ximagesrc: Draw the cursor only when it is active in the capturing region
authorAntonio Ospite <ao2@ao2.it>
Thu, 4 Sep 2014 14:10:51 +0000 (16:10 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 16 Sep 2014 07:32:39 +0000 (10:32 +0300)
Use XQueryPointer to check that the pointer is actually active inside
the capturing region.

This prevents drawing the cursor when the pointer is partially outside
of the captured region but not active inside the region; in particular
this avoids drawing the "window resize" cursor shapes to the captured
image when the mouse pointer crosses a window border.

NOTE that this is not only an optimization, this also happen to fix
a serious problem in multi-screen setups.

Because XFixes gives no information of what screen the pointer is on,
ximagesrc was always drawing the cursor on the captured screen even if
the mouse pointer was on another screen.

For example, when capturing from screen 1 (i.e. display-name=":0.1") the
cursor was drawn in the captured image even when the mouse pointer was
actually on screen 0, which is wrong and visually confusing.

https://bugzilla.gnome.org/show_bug.cgi?id=690646

sys/ximage/gstximagesrc.c

index e7c5256..97fed27 100644 (file)
@@ -373,6 +373,23 @@ gst_ximage_src_recalc (GstXImageSrc * src)
   return TRUE;
 }
 
+static gboolean
+gst_ximage_is_pointer_in_region (GstXImageSrc * src)
+{
+  Window window_returned;
+  int root_x, root_y;
+  int win_x, win_y;
+  unsigned int mask_return;
+  Bool on_window;
+
+  on_window = XQueryPointer (src->xcontext->disp, src->xwindow,
+      &window_returned, &window_returned, &root_x, &root_y, &win_x, &win_y,
+      &mask_return);
+
+  return (on_window && (win_x >= src->startx) && (win_y >= src->starty) &&
+      (win_x < src->endx) && (win_y < src->endy));
+}
+
 #ifdef HAVE_XFIXES
 static void
 composite_pixel (GstXContext * xcontext, guchar * dest, guchar * src)
@@ -700,7 +717,8 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
 #endif
 
 #ifdef HAVE_XFIXES
-  if (ximagesrc->show_pointer && ximagesrc->have_xfixes) {
+  if (ximagesrc->show_pointer && ximagesrc->have_xfixes
+      && gst_ximage_is_pointer_in_region (ximagesrc)) {
 
     GST_DEBUG_OBJECT (ximagesrc, "Using XFixes to draw cursor");
     /* get cursor */